├── .travis.yml ├── .gitignore ├── .settings ├── org.eclipse.m2e.core.prefs ├── org.eclipse.core.resources.prefs └── org.eclipse.jdt.core.prefs ├── examples ├── README ├── dummy_to_dummy.properties ├── access_to_postgresql.properties ├── mssql_to_postgresql.properties └── mysql_to_postgresql.properties ├── src └── main │ └── java │ └── pt │ └── evolute │ ├── utils │ ├── tables │ │ └── ColumnizedObject.java │ ├── error │ │ └── ErrorLogger.java │ ├── db │ │ ├── Retriever.java │ │ ├── ExecuterProvider.java │ │ ├── DBException.java │ │ ├── Executer.java │ │ ├── DBConstants.java │ │ ├── PrimaryKeyMetadataConstants.java │ │ ├── Connector.java │ │ ├── DriverProvider.java │ │ └── ForeignKeyMetadataConstants.java │ ├── sql │ │ ├── table │ │ │ ├── TableExpression.java │ │ │ ├── JoinBuilder.java │ │ │ ├── Table.java │ │ │ ├── JoinBuilderFactory.java │ │ │ ├── JoinExpression.java │ │ │ ├── DefaultTable.java │ │ │ ├── PostgreSQLJoinBuilder.java │ │ │ └── InformixJoinBuilder.java │ │ ├── expression │ │ │ ├── Or.java │ │ │ ├── And.java │ │ │ └── Atom.java │ │ ├── function │ │ │ ├── SQLFunction.java │ │ │ ├── SQLLength.java │ │ │ ├── SQLMax.java │ │ │ ├── SQLYear.java │ │ │ ├── SQLMonth.java │ │ │ ├── SQLAlias.java │ │ │ ├── SQLCast.java │ │ │ ├── SQLCount.java │ │ │ ├── SQLConcat.java │ │ │ └── SQLDistinct.java │ │ ├── condition │ │ │ ├── Less.java │ │ │ ├── Greater.java │ │ │ ├── LessOrEqual.java │ │ │ ├── GreaterOrEqual.java │ │ │ ├── NotILike.java │ │ │ ├── NotLike.java │ │ │ ├── Equal.java │ │ │ ├── Like.java │ │ │ ├── Different.java │ │ │ ├── NotIn.java │ │ │ ├── ILike.java │ │ │ ├── Between.java │ │ │ └── In.java │ │ ├── UpdateQuery.java │ │ ├── FieldIndex.java │ │ ├── SQLQuery.java │ │ ├── Condition.java │ │ ├── backend │ │ │ ├── HSQLDBBackend.java │ │ │ ├── Backend.java │ │ │ ├── PostgreSQLBackend.java │ │ │ └── BackendProvider.java │ │ ├── Field.java │ │ ├── Expression.java │ │ ├── Assignment.java │ │ ├── Update.java │ │ └── Insert.java │ ├── arrays │ │ ├── Virtual2DArray.java │ │ ├── exception │ │ │ └── EndOfArrayException.java │ │ ├── EvoArrays.java │ │ ├── IntArrayIntervalFinder.java │ │ ├── LightResultSet2DArray.java │ │ ├── CursorResultSet2DArray.java │ │ └── VectorArray.java │ ├── object │ │ ├── InvalidPropertyException.java │ │ ├── LightPropertyObject.java │ │ └── DefaultLightPropertyObject.java │ ├── ddl │ │ └── DDLDefaultValue.java │ ├── jdbc │ │ ├── StatementExecuter.java │ │ └── StatementExecuterFactory.java │ ├── dbmodel │ │ ├── DBColumn.java │ │ ├── DBHierarchy.java │ │ ├── DBReference.java │ │ └── DBTable.java │ ├── Singleton.java │ └── string │ │ ├── StringPlainer.java │ │ └── EvoStringUtils.java │ └── dbtransfer │ ├── db │ ├── beans │ │ ├── PrimaryKeyDefinition.java │ │ ├── TableDefinition.java │ │ ├── ColumnDefinition.java │ │ ├── Name.java │ │ ├── UniqueDefinition.java │ │ ├── ForeignKeyDefinition.java │ │ └── ConnectionDefinitionBean.java │ ├── DBConnector.java │ ├── dummy │ │ └── Dummy2DArray.java │ ├── helper │ │ ├── HelperManager.java │ │ ├── Helper.java │ │ ├── HsqlDBServerHelper.java │ │ ├── OracleServerHelper.java │ │ └── NullHelper.java │ ├── DBConnection.java │ ├── jackcess │ │ ├── Jackcess2DArray.java │ │ └── JackcessConnection.java │ └── PrimaryKeyValue.java │ ├── diff │ ├── CachedDBView.java │ ├── TableRow.java │ └── TablePage.java │ ├── Config.java │ ├── ConfigurationProperties.java │ ├── transfer │ └── ReportThread.java │ ├── Main.java │ └── analyse │ └── Analyser.java ├── .project ├── DEPENDENCIES ├── .classpath ├── vs_pgloader.io.txt ├── README.md └── pom.xml /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | install: mvn package 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | dbtransfer.iml 3 | build/ 4 | tmp/ 5 | target/ 6 | /.settings/ 7 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | Sample properties files. 2 | --- 3 | A good way to get connection properties is to use DBeaver (https://www.dbeaver.io/) to test the connection first. 4 | 5 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/tables/ColumnizedObject.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.tables; 2 | 3 | public interface ColumnizedObject 4 | { 5 | public OBJ_CLASS getValue(int col); 6 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/error/ErrorLogger.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.error; 2 | 3 | public class ErrorLogger { 4 | 5 | public static void logException( Exception ex) { 6 | // TODO Auto-generated method stub 7 | 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/Retriever.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.db; 2 | 3 | import pt.evolute.utils.arrays.Virtual2DArray; 4 | 5 | public interface Retriever 6 | { 7 | public void setResults(Virtual2DArray results); 8 | 9 | public void setException(DBException ex); 10 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/ExecuterProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ExecuterProvider.java 3 | * 4 | * Created on 26 de Maio de 2003, 18:16 5 | */ 6 | 7 | package pt.evolute.utils.db; 8 | 9 | /** 10 | * 11 | * @author lflores 12 | */ 13 | public interface ExecuterProvider 14 | { 15 | public Executer getExecuter(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/beans/PrimaryKeyDefinition.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.beans; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class PrimaryKeyDefinition 7 | { 8 | public String name; 9 | public List columns = new ArrayList(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/table/TableExpression.java: -------------------------------------------------------------------------------- 1 | /* 2 | * TableExpression.java 3 | * 4 | * Created on 2 de Junho de 2005, 16:20 5 | */ 6 | 7 | package pt.evolute.utils.sql.table; 8 | 9 | /** 10 | * 11 | * @author fpalma 12 | */ 13 | public interface TableExpression 14 | { 15 | public String getHeader(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/arrays/Virtual2DArray.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.arrays; 2 | 3 | 4 | public interface Virtual2DArray 5 | { 6 | public RETURN_TYPE get(int row, int col); 7 | 8 | public int columnCount(); 9 | 10 | public int rowCount(); 11 | 12 | public Object[][] getObjects(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/expression/Or.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.expression; 2 | 3 | import pt.evolute.utils.sql.Expression; 4 | 5 | public class Or extends Expression 6 | { 7 | public Or( Expression left, Expression right ) 8 | { 9 | super( left, right ); 10 | } 11 | 12 | @Override 13 | public String getSymbol() 14 | { 15 | return "OR"; 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/expression/And.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.expression; 2 | 3 | import pt.evolute.utils.sql.Expression; 4 | 5 | public class And extends Expression 6 | { 7 | public And( Expression left, Expression right ) 8 | { 9 | super( left, right ); 10 | } 11 | 12 | @Override 13 | public String getSymbol() 14 | { 15 | return "AND"; 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLFunction.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Field; 4 | /** 5 | * 6 | * @author fpalma 7 | */ 8 | public abstract class SQLFunction extends Field 9 | { 10 | public SQLFunction( String representation ) 11 | { 12 | super( representation ); 13 | } 14 | 15 | public abstract String getSymbol(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/Less.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | 6 | public class Less extends Condition 7 | { 8 | public Less( Operand left, Operand right ) 9 | { 10 | super( left, right ); 11 | } 12 | 13 | @Override 14 | public String getSymbol() 15 | { 16 | return "<"; 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/Greater.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | 6 | public class Greater extends Condition 7 | { 8 | public Greater( Operand left, Operand right ) 9 | { 10 | super( left, right ); 11 | } 12 | 13 | @Override 14 | public String getSymbol() 15 | { 16 | return ">"; 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/LessOrEqual.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | 6 | public class LessOrEqual extends Condition 7 | { 8 | public LessOrEqual( Operand left, Operand right ) 9 | { 10 | super( left, right ); 11 | } 12 | 13 | @Override 14 | public String getSymbol() 15 | { 16 | return "<="; 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/GreaterOrEqual.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | 6 | public class GreaterOrEqual extends Condition 7 | { 8 | public GreaterOrEqual( Operand left, Operand right ) 9 | { 10 | super( left, right ); 11 | } 12 | 13 | @Override 14 | public String getSymbol() 15 | { 16 | return ">="; 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/NotILike.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | 6 | public class NotILike extends Condition 7 | { 8 | 9 | public NotILike( Operand left, Operand right ) 10 | { 11 | super( left, right ); 12 | } 13 | 14 | @Override 15 | public String getSymbol() 16 | { 17 | return "NOT ILIKE"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/NotLike.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | 6 | public class NotLike extends Condition 7 | { 8 | 9 | public NotLike( Operand left, Operand right ) 10 | { 11 | super( left, right ); 12 | } 13 | 14 | @Override 15 | public String getSymbol() 16 | { 17 | return "NOT LIKE"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/table/JoinBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * JoinBuilder.java 3 | * 4 | * Created on 30 de Maio de 2005, 16:17 5 | */ 6 | 7 | package pt.evolute.utils.sql.table; 8 | 9 | import pt.evolute.utils.sql.Expression; 10 | 11 | /** 12 | * 13 | * @author fpalma 14 | */ 15 | public interface JoinBuilder 16 | { 17 | public String getDatabaseType(); 18 | public String getHeader(); 19 | public Expression getFilter(); 20 | } 21 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled 5 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 6 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore 7 | org.eclipse.jdt.core.compiler.release=disabled 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/UpdateQuery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * UpdateQuery.java 3 | * 4 | * Created on 12 de Junho de 2003, 19:44 5 | */ 6 | 7 | package pt.evolute.utils.sql; 8 | 9 | import java.sql.SQLException; 10 | 11 | /** 12 | * 13 | * @author informatica 14 | */ 15 | public interface UpdateQuery extends SQLQuery 16 | { 17 | public boolean isBatch(); 18 | 19 | public String[] getBatch(); 20 | 21 | public void fillParameters(Object stm) 22 | throws SQLException; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/table/Table.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.table; 2 | 3 | import pt.evolute.utils.sql.Field; 4 | /** 5 | * 6 | * @author fpalma 7 | */ 8 | public interface Table extends TableExpression 9 | { 10 | public String []getAllFieldNames(); 11 | public Field []getAllFields(); 12 | public Field []getFields(String names[]); 13 | public Field getField(String fieldName); 14 | public String getName(); 15 | public String getAlias(); 16 | public boolean isTemp(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/DBException.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.db; 2 | 3 | public class DBException extends Exception 4 | { 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | public DBException( String message ) 11 | { 12 | super( message ); 13 | } 14 | 15 | public DBException( Throwable cause ) 16 | { 17 | super( cause ); 18 | } 19 | 20 | public DBException( String message, Throwable cause ) 21 | { 22 | super( message, cause ); 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/Equal.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | 6 | public class Equal extends Condition 7 | { 8 | public Equal( Operand left, Operand right ) 9 | { 10 | super( left, right ); 11 | } 12 | 13 | @Override 14 | public String getSymbol() 15 | { 16 | if( iRight.isNull() ) 17 | { 18 | return "IS"; 19 | } 20 | else 21 | { 22 | return "="; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/FieldIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * FieldIndex.java 3 | * 4 | * Created on 6 de Junho de 2005, 13:05 5 | */ 6 | 7 | package pt.evolute.utils.sql; 8 | 9 | /** 10 | * 11 | * @author fpalma 12 | */ 13 | public class FieldIndex extends Field 14 | { 15 | protected Operand indexed; 16 | protected Integer index; 17 | 18 | public FieldIndex( Operand indexed, Integer index ) 19 | { 20 | super( index.toString() ); 21 | this.indexed = indexed; 22 | this.index = index; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/Like.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | /** 6 | * 7 | * @author lflores 8 | */ 9 | public class Like extends Condition 10 | { 11 | 12 | /** Creates a new instance of Like */ 13 | public Like( Operand left, Operand right ) 14 | { 15 | super( left, right ); 16 | } 17 | 18 | @Override 19 | public String getSymbol() 20 | { 21 | return "LIKE"; 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/object/InvalidPropertyException.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.object; 2 | 3 | /** 4 | * 5 | * @author fpalma 6 | */ 7 | public class InvalidPropertyException 8 | extends RuntimeException 9 | { 10 | 11 | private static final long serialVersionUID = 1L; 12 | 13 | /** Creates a new instance of InvalidPropertyException */ 14 | public InvalidPropertyException( String property, String message ) 15 | { 16 | super( "Invalid property: " + property + "\n" + message ); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/Different.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | 6 | public class Different extends Condition 7 | { 8 | public Different( Operand left, Operand right ) 9 | { 10 | super( left, right ); 11 | } 12 | 13 | @Override 14 | public String getSymbol() 15 | { 16 | if( iRight.isNull() ) 17 | { 18 | return "IS NOT"; 19 | } 20 | else 21 | { 22 | return "<>"; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/expression/Atom.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.expression; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Expression; 5 | 6 | 7 | public class Atom extends Expression 8 | { 9 | public Atom( Condition cond ) 10 | { 11 | super( cond ); 12 | } 13 | 14 | @Override 15 | public String toString() 16 | { 17 | iCondition.setBackend( backend ); 18 | return iCondition.toString(); 19 | } 20 | 21 | @Override 22 | public String getSymbol() 23 | { 24 | return ""; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/SQLQuery.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql; 2 | 3 | import pt.evolute.utils.arrays.Virtual2DArray; 4 | import pt.evolute.utils.db.ExecuterProvider; 5 | import pt.evolute.utils.sql.backend.Backend; 6 | 7 | public interface SQLQuery 8 | { 9 | public void execute() 10 | throws Exception; 11 | 12 | public void execute(ExecuterProvider provider) 13 | throws Exception; 14 | 15 | public Object[][] getObjects(); 16 | 17 | public Virtual2DArray getCursorObjects(); 18 | 19 | public void setBackend(Backend backend); 20 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/arrays/exception/EndOfArrayException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | package pt.evolute.utils.arrays.exception; 8 | 9 | /** 10 | * 11 | * @author lflores 12 | */ 13 | public class EndOfArrayException extends RuntimeException 14 | { 15 | 16 | /** 17 | * 18 | */ 19 | private static final long serialVersionUID = 8951121841780724137L; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/ddl/DDLDefaultValue.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.ddl; 2 | 3 | public class DDLDefaultValue 4 | { 5 | protected final Integer type; 6 | protected final String value; 7 | 8 | public DDLDefaultValue(Integer type, String value) 9 | { 10 | super(); 11 | this.type = type; 12 | this.value = value; 13 | } 14 | 15 | /** 16 | * @return the type 17 | */ 18 | public Integer getType() 19 | { 20 | return type; 21 | } 22 | 23 | /** 24 | * @return the value 25 | */ 26 | public String getValue() 27 | { 28 | return value; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/Executer.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.db; 2 | 3 | import pt.evolute.utils.arrays.Virtual2DArray; 4 | import pt.evolute.utils.sql.SQLQuery; 5 | 6 | public interface Executer 7 | { 8 | // o executer nao tem connection, so o dbmanager e q tem, 9 | // o executer e so uma chave 10 | 11 | public void executeQuery(SQLQuery query, Retriever retriever) 12 | throws DBException; 13 | 14 | public Virtual2DArray executeQuery(SQLQuery query) 15 | throws DBException; 16 | // adicionar metodos sincronos (com threads e listener, tipo executeLater ) 17 | 18 | public void close(); 19 | } 20 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | dbtransfer_gh 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/jdbc/StatementExecuter.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.jdbc; 2 | 3 | import pt.evolute.utils.arrays.Virtual2DArray; 4 | import pt.evolute.utils.sql.SQLQuery; 5 | 6 | public interface StatementExecuter 7 | { 8 | public Virtual2DArray executeSelectStatementWithCursor(String stm, SQLQuery query) 9 | throws Exception; 10 | 11 | public Virtual2DArray executeUpdateStatementWithCursor(String stm, SQLQuery query) 12 | throws Exception; 13 | 14 | public Object[][] executeSelectStatement(String stm, SQLQuery query) 15 | throws Exception; 16 | 17 | public Object[][] executeUpdateStatement(String stm, SQLQuery query) 18 | throws Exception; 19 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/DBConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DBConstants.java 3 | * 4 | * Created on 30 de Maio de 2005, 15:53 5 | */ 6 | 7 | package pt.evolute.utils.db; 8 | 9 | /** 10 | * 11 | * @author fpalma 12 | */ 13 | public interface DBConstants 14 | { 15 | public static final String DB_INFORMIX = "INFORMIX"; 16 | public static final String DB_POSTGRESQL = "POSTGRESQL"; 17 | public static final String DB_HSQL = "HSQL"; 18 | public static final String DB_SQLSERVER = "SQLSERVER"; 19 | 20 | public static final String CURRENT_TIME = "CURRENT_TIME"; 21 | public static final String CURRENT_DATE = "CURRENT_DATE"; 22 | public static final String CURRENT_DATETIME = "CURRENT_DATETIME"; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/object/LightPropertyObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * LightPropertyObject.java 3 | * 4 | * Created on 30 de Novembro de 2006, 19:03 5 | * 6 | * To change this template, choose Tools | Template Manager 7 | * and open the template in the editor. 8 | */ 9 | 10 | package pt.evolute.utils.object; 11 | 12 | import java.util.Map; 13 | 14 | /** 15 | * 16 | * @author fpalma 17 | */ 18 | public interface LightPropertyObject 19 | { 20 | public Object get(String fieldName); 21 | 22 | public String[] getPropertyNames(); 23 | 24 | public Map getMapData(); 25 | 26 | public void set(String fieldName, Object value); 27 | 28 | public void setMapData(Map map); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/NotIn.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | 5 | public class NotIn extends In 6 | { 7 | private static final String connector_string = "AND"; 8 | private static final String between_prefix_string = "NOT "; 9 | private static final String in_string = "NOT IN"; 10 | 11 | public NotIn( Operand left, Operand right ) 12 | { 13 | super( left, right ); 14 | } 15 | 16 | @Override 17 | public String getConnector() 18 | { 19 | return connector_string; 20 | } 21 | 22 | @Override 23 | public String getBetweenPrefix() 24 | { 25 | return between_prefix_string; 26 | } 27 | 28 | @Override 29 | public String getInString() 30 | { 31 | return in_string; 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/beans/TableDefinition.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.beans; 2 | 3 | public class TableDefinition extends Name 4 | { 5 | public TableDefinition( String original ) 6 | { 7 | super( original ); 8 | } 9 | 10 | @Override 11 | public String toString() 12 | { 13 | return saneName; 14 | } 15 | 16 | @Override 17 | public boolean equals( Object o ) 18 | { 19 | boolean eq = o instanceof TableDefinition; 20 | if( eq ) 21 | { 22 | eq = originalName.equals( ((TableDefinition)o).originalName ); 23 | } 24 | return eq; 25 | } 26 | 27 | @Override 28 | public int hashCode() 29 | { 30 | int hash = 3; 31 | hash = 53 * ( hash + (this.originalName != null ? this.originalName.hashCode() : 0) ); 32 | return hash; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLLength.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | 6 | public class SQLLength extends SQLFunction 7 | { 8 | protected Operand parameter; 9 | 10 | public SQLLength( Operand parameter ) 11 | { 12 | super( "LENGTH" ); 13 | this.parameter = parameter; 14 | } 15 | 16 | @Override 17 | public String getSymbol() 18 | { 19 | return "" + getBackend().getUserFunctionName( this ); 20 | } 21 | 22 | @Override 23 | public String toString() 24 | { 25 | return getSymbol() + "(" + parameter + ")"; 26 | } 27 | 28 | @Override 29 | public void setBackend( Backend backend ) 30 | { 31 | super.setBackend( backend ); 32 | if( parameter != null ) 33 | { 34 | parameter.setBackend( backend ); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLMax.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | 6 | public class SQLMax extends SQLFunction 7 | { 8 | protected Operand parameter; 9 | 10 | /** Creates a new instance of Max */ 11 | public SQLMax( Operand parameter ) 12 | { 13 | super( "Max" ); 14 | this.parameter = parameter; 15 | } 16 | 17 | @Override 18 | public String getSymbol() 19 | { 20 | return "" + getBackend().getUserFunctionName( this ); 21 | } 22 | 23 | @Override 24 | public String toString() 25 | { 26 | return getSymbol() + "(" + parameter + ")"; 27 | } 28 | 29 | @Override 30 | public void setBackend( Backend backend ) 31 | { 32 | super.setBackend( backend ); 33 | if( parameter != null ) 34 | { 35 | parameter.setBackend( backend ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLYear.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | /** 6 | * 7 | * @author fpalma 8 | */ 9 | public class SQLYear extends SQLFunction 10 | { 11 | protected Operand parameter; 12 | 13 | /** Creates a new instance of SQLYear */ 14 | public SQLYear( Operand parameter ) 15 | { 16 | super( "YEAR" ); 17 | this.parameter = parameter; 18 | } 19 | 20 | @Override 21 | public String getSymbol() 22 | { 23 | return "YEAR"; 24 | } 25 | 26 | @Override 27 | public String toString() 28 | { 29 | return getSymbol() + "(" + parameter + ")"; 30 | } 31 | 32 | @Override 33 | public void setBackend( Backend backend ) 34 | { 35 | super.setBackend( backend ); 36 | if( parameter != null ) 37 | { 38 | parameter.setBackend( backend ); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLMonth.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | /** 6 | * 7 | * @author fpalma 8 | */ 9 | public class SQLMonth extends SQLFunction 10 | { 11 | protected Operand parameter; 12 | 13 | /** Creates a new instance of SQLMonth */ 14 | public SQLMonth( Operand parameter ) 15 | { 16 | super( "MONTH" ); 17 | this.parameter = parameter; 18 | } 19 | 20 | @Override 21 | public String getSymbol() 22 | { 23 | return "MONTH"; 24 | } 25 | 26 | @Override 27 | public String toString() 28 | { 29 | return getSymbol() + "(" + parameter + ")"; 30 | } 31 | 32 | @Override 33 | public void setBackend( Backend backend ) 34 | { 35 | super.setBackend( backend ); 36 | if( parameter != null ) 37 | { 38 | parameter.setBackend( backend ); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /examples/dummy_to_dummy.properties: -------------------------------------------------------------------------------- 1 | #SOURCE DATABASE - DUMMY tablename / # of millions of rows 2 | URL_DB_SOURCE = dummy://table/3 3 | USER_DB_SOURCE = user 4 | PASSWORD_DB_SOURCE = pass 5 | #DESTINATION DATABASE - PostgreSQL 6 | URL_DB_DESTINATION = dummy:// 7 | USER_DB_DESTINATION = u 8 | PASSWORD_DB_DESTINATION = p 9 | 10 | #OPTIONS 11 | #TRANSFERS EMPTY TABLES IF FALSE 12 | ONLY_NOT_EMPTY = true 13 | #NUMBER OF TRANSFER THREADS, WHEN DESTINATION IS MSSQL, THERE SHOULD BE ONLY 1 TRANSFER THREAD 14 | TRANSFER.THREADS = 1 15 | #WHEN APPLYING THE CONSTRAINTS, DOESN'T GENERATE NORMALIZES NAMES , USES ORIGINAL NAMES 16 | CONSTRAIN.KEEP_NAMES = false 17 | #TURN ON/OFF DEBUGGING 18 | DEBUG = true 19 | #REORDER TABLES TO ALLOW TRANSFER WITH FOREIGN APPLIED 20 | TRANSFER.CHECK_DEPS = true 21 | 22 | #NEXT PROPERTIES CAN BE TURNED ON INDEPENDENTLY, OR AT THE SAME TIME 23 | ANALYSE = true 24 | TRANSFER = true 25 | CONSTRAIN = true 26 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/Condition.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql; 2 | 3 | import pt.evolute.utils.sql.backend.Backend; 4 | 5 | 6 | public abstract class Condition 7 | { 8 | protected Operand iLeft; 9 | protected Operand iRight; 10 | 11 | private Backend backend = null; 12 | 13 | public Condition( Operand left, Operand right ) 14 | { 15 | iLeft = left; 16 | iRight = right; 17 | } 18 | 19 | @Override 20 | public String toString() 21 | { 22 | return getLeft() + " " + getSymbol() + " " + getRight(); 23 | } 24 | 25 | public String getLeft() 26 | { 27 | iLeft.setBackend( backend ); 28 | return iLeft.toString(); 29 | } 30 | 31 | public String getRight() 32 | { 33 | iRight.setBackend( backend ); 34 | return iRight.toString(); 35 | } 36 | 37 | public void setBackend( Backend backend ) 38 | { 39 | this.backend = backend; 40 | } 41 | 42 | public Backend getBackend() 43 | { 44 | return backend; 45 | } 46 | 47 | public abstract String getSymbol(); 48 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/arrays/EvoArrays.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package pt.evolute.utils.arrays; 7 | 8 | import java.lang.reflect.Array; 9 | import java.util.Arrays; 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | 13 | /** 14 | * 15 | * @author lflores 16 | */ 17 | public class EvoArrays 18 | { 19 | @SuppressWarnings("unchecked") 20 | public static T[] sortAndDistinct( T[] a ) 21 | { 22 | Arrays.sort( a ); 23 | List list = new LinkedList(); 24 | T old = null; 25 | boolean inited = false; 26 | for( T e: a ) 27 | { 28 | if( inited ) 29 | { 30 | if( old != e 31 | && ( e == null || !e.equals( old ) ) ) 32 | { 33 | list.add( e ); 34 | } 35 | } 36 | else 37 | { 38 | list.add( e ); 39 | inited = true; 40 | } 41 | old = e; 42 | } 43 | return list.toArray( ( T[] )Array.newInstance( old.getClass(), list.size() ) ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/table/JoinBuilderFactory.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.table; 2 | 3 | import pt.evolute.utils.db.DBConstants; 4 | /** 5 | * 6 | * @author fpalma 7 | */ 8 | public class JoinBuilderFactory implements DBConstants 9 | { 10 | 11 | /** Creates a new instance of JoinBuilderFactory */ 12 | private JoinBuilderFactory() 13 | { 14 | } 15 | 16 | public static JoinBuilder getJoinBuilder( JoinExpression join ) 17 | { 18 | if( DB_INFORMIX.equals( join.joinDatabaseType ) ) 19 | { 20 | return new InformixJoinBuilder( join.table, join.outer, join.joins, join.conditions ); 21 | } 22 | else if( DB_POSTGRESQL.equals( join.joinDatabaseType ) ) 23 | { 24 | return new PostgreSQLJoinBuilder( join.table, join.outer, join.joins, join.conditions ); 25 | } 26 | else if( DB_HSQL.equals( join.joinDatabaseType ) ) 27 | { 28 | return new PostgreSQLJoinBuilder( join.table, join.outer, join.joins, join.conditions ); 29 | } 30 | throw new RuntimeException( "Database not implemented: " + join.joinDatabaseType ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLAlias.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | 6 | /** 7 | * 8 | * @author fpalma 9 | */ 10 | public class SQLAlias extends SQLFunction 11 | { 12 | protected Operand parameter; 13 | protected String alias; 14 | 15 | /** Creates a new instance of SQLAlias */ 16 | public SQLAlias( Operand parameter, String alias ) 17 | { 18 | super( "" ); 19 | this.parameter = parameter; 20 | this.alias = alias; 21 | } 22 | 23 | @Override 24 | public String getSymbol() 25 | { 26 | return ""; 27 | } 28 | 29 | @Override 30 | public String toString() 31 | { 32 | return alias; 33 | } 34 | 35 | @Override 36 | public String toHeaderString() 37 | { 38 | return parameter.toString() + " AS " + alias; 39 | } 40 | 41 | @Override 42 | public void setBackend( Backend backend ) 43 | { 44 | super.setBackend( backend ); 45 | if( parameter != null ) 46 | { 47 | parameter.setBackend( backend ); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /DEPENDENCIES: -------------------------------------------------------------------------------- 1 | lib/jackcess-1.2.12.jar 2 | Java Library for MS Access 3 | http://jackcess.sourceforge.net 4 | Enables the use of source mdb files on Windows and non-Windows operating systems 5 | 6 | lib/mysql-connector-java-5.1.30-bin.jar 7 | MySQL jdbc driver 8 | https://dev.mysql.com/downloads/connector/j/ 9 | 10 | lib/ojdbc6.jar 11 | Oracle jdbc driver 12 | license: http://www.oracle.com/technetwork/licenses/distribution-license-152002.html 13 | download: http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html 14 | documentation: http://www.oracle.com/technetwork/indexes/documentation/index.html 15 | 16 | lib/postgresql-9.3-1101.jdbc41.jar 17 | PostgreSQL jdbc driver 18 | license: http://jdbc.postgresql.org/about/license.html 19 | download: http://jdbc.postgresql.org 20 | 21 | lib/sqljdbc4.jar 22 | SQLServer official jdbc driver 23 | http://msdn.microsoft.com/en-us/sqlserver/aa937724.aspx 24 | 25 | lib/jt400.jar 26 | JTOpen: The Open Source version of the IBM Toolbox for Java 27 | downlaod: http://jt400.sourceforge.net/ 28 | license: http://opensource.org/licenses/ibmpl.php 29 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLCast.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | /** 6 | * 7 | * @author fpalma 8 | * 9 | * Use {@link com.evolute.utils.sql.function.Max} instead 10 | */ 11 | public class SQLCast extends SQLFunction 12 | { 13 | protected Operand parameter; 14 | protected String type; 15 | 16 | /** Creates a new instance of Max */ 17 | public SQLCast( Operand parameter, String type ) 18 | { 19 | super( "CAST" ); 20 | this.parameter = parameter; 21 | this.type = type; 22 | } 23 | 24 | @Override 25 | public String getSymbol() 26 | { 27 | return "" + getBackend().getUserFunctionName( this ); 28 | } 29 | 30 | @Override 31 | public String toString() 32 | { 33 | return getSymbol() + "( " + parameter + " AS " + type + " )"; 34 | } 35 | 36 | @Override 37 | public void setBackend( Backend backend ) 38 | { 39 | super.setBackend( backend ); 40 | if( parameter != null ) 41 | { 42 | parameter.setBackend( backend ); 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLCount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SQLCount.java 3 | * 4 | * Created on 6 de Junho de 2005, 13:15 5 | */ 6 | 7 | package pt.evolute.utils.sql.function; 8 | 9 | import pt.evolute.utils.sql.Field; 10 | import pt.evolute.utils.sql.Operand; 11 | import pt.evolute.utils.sql.backend.Backend; 12 | /** 13 | * 14 | * @author fpalma 15 | */ 16 | public class SQLCount extends SQLFunction 17 | { 18 | protected Operand parameter; 19 | 20 | public SQLCount() 21 | { 22 | this( new Field( "*" ) ); 23 | } 24 | 25 | /** Creates a new instance of SQLCount */ 26 | public SQLCount( Operand parameter ) 27 | { 28 | super( "COUNT" ); 29 | this.parameter = parameter; 30 | } 31 | 32 | @Override 33 | public String getSymbol() 34 | { 35 | return "COUNT"; 36 | } 37 | 38 | @Override 39 | public String toString() 40 | { 41 | return getSymbol() + "(" + parameter + ")"; 42 | } 43 | 44 | @Override 45 | public void setBackend( Backend backend ) 46 | { 47 | super.setBackend( backend ); 48 | if( parameter != null ) 49 | { 50 | parameter.setBackend( backend ); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/access_to_postgresql.properties: -------------------------------------------------------------------------------- 1 | #SOURCE DATABASE - Access 2 | URL_DB_SOURCE = jackcess://PATH/TO/FILE> 3 | USER_DB_SOURCE = 4 | PASSWORD_DB_SOURCE = 5 | #DESTINATION DATABASE - PostgreSQL 6 | URL_DB_DESTINATION = jdbc:postgresql://:/ 7 | USER_DB_DESTINATION = 8 | PASSWORD_DB_DESTINATION = 9 | 10 | #OPTIONS 11 | #TRANSFERS EMPTY TABLES IF FALSE 12 | ONLY_NOT_EMPTY = 13 | #NUMBER OF TRANSFER THREADS, WHEN DESTINATION IS MSSQL, THERE SHOULD BE ONLY 1 TRANSFER THREAD 14 | TRANSFER.THREADS = 4 15 | #TRANSLATES MySQL 'BIT' TO PostgreSQL 'BOOLEAN' 16 | MYSQL.NORMALIZE.BIT_BOOLEAN = 17 | #WHEN APPLYING THE CONSTRAINTS, DOESN'T GENERATE NORMALIZES NAMES , USES ORIGINAL NAMES 18 | CONSTRAIN.KEEP_NAMES = 19 | #TURN ON/OFF DEBUGGING 20 | DEBUG = 21 | #REORDER TABLES TO ALLOW TRANSFER WITH FOREIGN APPLIED 22 | TRANSFER.CHECK_DEPS = 23 | 24 | #NEXT PROPERTIES CAN BE TURNED ON INDEPENDENTLY, OR AT THE SAME TIME 25 | ANALYSE = 26 | TRANSFER = 27 | CONSTRAIN = 28 | -------------------------------------------------------------------------------- /examples/mssql_to_postgresql.properties: -------------------------------------------------------------------------------- 1 | #SOURCE DATABASE - MSSQL 2 | URL_DB_SOURCE = jdbc:sqlserver://[\:;DatabaseName= 3 | USER_DB_SOURCE = 4 | PASSWORD_DB_SOURCE = 5 | #DESTINATION DATABASE - PostgreSQL 6 | URL_DB_DESTINATION = jdbc:postgresql://:/ 7 | USER_DB_DESTINATION = 8 | PASSWORD_DB_DESTINATION = 9 | 10 | #OPTIONS 11 | #TRANSFERS EMPTY TABLES IF FALSE 12 | ONLY_NOT_EMPTY = 13 | #NUMBER OF TRANSFER THREADS, WHEN DESTINATION IS MSSQL, THERE SHOULD BE ONLY 1 TRANSFER THREAD 14 | TRANSFER.THREADS = 2 15 | #WHEN APPLYING THE CONSTRAINTS, DOESN'T GENERATE NORMALIZES NAMES , USES ORIGINAL NAMES 16 | CONSTRAIN.KEEP_NAMES = 17 | #TURN ON/OFF DEBUGGING 18 | DEBUG = 19 | #REORDER TABLES TO ALLOW TRANSFER WITH FOREIGN APPLIED 20 | TRANSFER.CHECK_DEPS = 21 | 22 | #NEXT PROPERTIES CAN BE TURNED ON INDEPENDENTLY, OR AT THE SAME TIME 23 | ANALYSE = 24 | TRANSFER = 25 | CONSTRAIN = 26 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/beans/ColumnDefinition.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.beans; 2 | 3 | /** 4 | * 5 | * @author lflores 6 | */ 7 | public class ColumnDefinition 8 | { 9 | public Name name; 10 | public String sqlTypeName; 11 | public int sqlType; 12 | public Integer sqlSize; 13 | public String defaultValue; 14 | public boolean isNotNull; 15 | public TableDefinition referencedTable; 16 | public ColumnDefinition referencedColumn; 17 | public boolean isPrimaryKey; 18 | public String foreignKeyName; 19 | 20 | @Override 21 | public String toString() 22 | { 23 | return name.saneName; 24 | } 25 | 26 | @Override 27 | public boolean equals( Object o ) 28 | { 29 | boolean eq = o instanceof ColumnDefinition; 30 | if( eq ) 31 | { 32 | eq = name.originalName.equals( ((ColumnDefinition)o).name.originalName ); 33 | } 34 | return eq; 35 | } 36 | 37 | @Override 38 | public int hashCode() 39 | { 40 | int hash = 3; 41 | hash = 53 * ( hash + (this.name.originalName != null ? this.name.originalName.hashCode() : 0) ); 42 | return hash; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/beans/Name.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.beans; 2 | 3 | import pt.evolute.utils.string.StringPlainer; 4 | 5 | public class Name 6 | { 7 | public final String saneName; 8 | public final String originalName; 9 | 10 | public Name( String original ) 11 | { 12 | originalName = original; 13 | String sane = original; 14 | if( sane.contains( " " ) ) 15 | { 16 | sane = sane.replace( ' ', '_' ); 17 | } 18 | if( sane.contains( "." ) ) 19 | { 20 | sane = sane.replace( '.', '_' ); 21 | } 22 | if( sane.contains( "\"" ) ) 23 | { 24 | sane = sane.replace( '\"', ' ' ).trim(); 25 | } 26 | saneName = StringPlainer.convertString( sane ); 27 | } 28 | 29 | @Override 30 | public String toString() 31 | { 32 | return saneName; 33 | } 34 | 35 | @Override 36 | public boolean equals( Object o ) 37 | { 38 | return originalName.equals( o ); 39 | } 40 | 41 | @Override 42 | public int hashCode() 43 | { 44 | int hash = 3; 45 | hash = 53 * hash + (this.originalName != null ? this.originalName.hashCode() : 0); 46 | return hash; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /examples/mysql_to_postgresql.properties: -------------------------------------------------------------------------------- 1 | #SOURCE DATABASE - MySQL / MariaDB 2 | URL_DB_SOURCE = jdbc:mysql://:/ 3 | USER_DB_SOURCE = 4 | PASSWORD_DB_SOURCE = 5 | #DESTINATION DATABASE - PostgreSQL 6 | URL_DB_DESTINATION = jdbc:postgresql://:/ 7 | USER_DB_DESTINATION = 8 | PASSWORD_DB_DESTINATION = 9 | 10 | #OPTIONS 11 | #TRANSFERS EMPTY TABLES IF FALSE 12 | ONLY_NOT_EMPTY = 13 | #NUMBER OF TRANSFER THREADS, WHEN DESTINATION IS MSSQL, THERE SHOULD BE ONLY 1 TRANSFER THREAD 14 | TRANSFER.THREADS = 4 15 | #TRANSLATES MySQL 'BIT' TO PostgreSQL 'BOOLEAN' 16 | MYSQL.NORMALIZE.BIT_BOOLEAN = 17 | #WHEN APPLYING THE CONSTRAINTS, DOESN'T GENERATE NORMALIZES NAMES , USES ORIGINAL NAMES 18 | CONSTRAIN.KEEP_NAMES = 19 | #TURN ON/OFF DEBUGGING 20 | DEBUG = 21 | #REORDER TABLES TO ALLOW TRANSFER WITH FOREIGN APPLIED 22 | TRANSFER.CHECK_DEPS = 23 | 24 | #NEXT PROPERTIES CAN BE TURNED ON INDEPENDENTLY, OR AT THE SAME TIME 25 | ANALYSE = 26 | TRANSFER = 27 | CONSTRAIN = 28 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/ILike.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | /** 6 | * 7 | * @author lflores 8 | */ 9 | public class ILike extends Condition 10 | { 11 | 12 | /** Creates a new instance of ILike */ 13 | public ILike( Operand left, Operand right ) 14 | { 15 | super( left, right ); 16 | } 17 | 18 | @Override 19 | public String getSymbol() 20 | { 21 | return getBackend().supportsILike() ? "ILIKE" : "LIKE"; 22 | } 23 | // SQLServer '=' && 'LIKE' are case INsensitive ! 24 | 25 | 26 | // public String getLeft() 27 | // { 28 | // String str = super.getLeft(); 29 | // if( !getBackend().supportsILike() ) 30 | // { 31 | // if( iLeft instanceof Field ) 32 | // { 33 | // str = "lower( " + str + " )"; 34 | // } 35 | // else 36 | // { 37 | // str = str.toLowerCase(); 38 | // } 39 | // } 40 | // return str; 41 | // } 42 | // 43 | // public String getRight() 44 | // { 45 | // String str = super.getRight(); 46 | // if( !getBackend().supportsILike() ) 47 | // { 48 | // if( str != null ) 49 | // { 50 | // str = str.toLowerCase(); 51 | // } 52 | // } 53 | // return str; 54 | // } 55 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/backend/HSQLDBBackend.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.backend; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import java.sql.Statement; 6 | 7 | 8 | public class HSQLDBBackend extends DefaultBackend 9 | { 10 | // must drop 1.8 support (used in querbio) 11 | // private static final String INIT_QUERY[] = new String[]{ "SET DATABASE DEFAULT TABLE TYPE CACHED" }; 12 | 13 | public HSQLDBBackend() 14 | { 15 | } 16 | 17 | /* @Override 18 | public String[] getInitQuery() 19 | { 20 | return INIT_QUERY; 21 | } 22 | */ 23 | 24 | @Override 25 | public boolean supportsReturnGeneratedKeys() 26 | { 27 | return false; 28 | } 29 | 30 | @Override 31 | public String portSyntax( CharSequence sql ) 32 | { 33 | String query = sql.toString(); 34 | if( query != null && !query.isEmpty() ) 35 | { 36 | query = query.replaceAll( "(?i)serial", "identity" ); 37 | } 38 | return query; 39 | } 40 | 41 | @Override 42 | public boolean isValid(Connection con) 43 | throws SQLException 44 | 45 | { 46 | Statement stm = con.createStatement(); 47 | stm.execute( "SELECT COUNT(*) FROM INFORMATION_SCHEMA.SYSTEM_TABLES" ); 48 | stm.close(); 49 | return true; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/beans/UniqueDefinition.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.beans; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import pt.evolute.dbtransfer.constrain.Constrainer; 7 | import pt.evolute.dbtransfer.db.helper.HelperManager; 8 | 9 | public class UniqueDefinition 10 | { 11 | private static final boolean honorNames; 12 | static 13 | { 14 | honorNames = "true".equals( HelperManager.getProperties().get( Constrainer.CONSTRAIN_KEEP_NAMES ) ); 15 | } 16 | 17 | public final Name table; 18 | public final String name; 19 | public final List columns = new ArrayList(); 20 | 21 | public String outputName = null; 22 | 23 | public UniqueDefinition( String n, Name t ) 24 | { 25 | name = n; 26 | table = t; 27 | } 28 | 29 | public String getOutputName() 30 | { 31 | if( outputName == null ) 32 | { 33 | if( honorNames ) 34 | { 35 | outputName = name; 36 | } 37 | else 38 | { 39 | outputName = table.saneName + "_"; 40 | for( String col: columns ) 41 | { 42 | outputName += col + "_"; 43 | } 44 | outputName += "uniq"; 45 | } 46 | } 47 | return outputName; 48 | } 49 | 50 | public String getOriginalName() 51 | { 52 | return name; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/DBConnector.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db; 2 | 3 | import pt.evolute.dbtransfer.db.beans.ConnectionDefinitionBean; 4 | import pt.evolute.dbtransfer.db.dummy.DummyConnection; 5 | import pt.evolute.dbtransfer.db.jackcess.JackcessConnection; 6 | import pt.evolute.dbtransfer.db.jdbc.JDBCConnection; 7 | 8 | /** 9 | * 10 | * @author lflores 11 | */ 12 | public class DBConnector 13 | { 14 | public static DBConnection getConnection( ConnectionDefinitionBean bean, boolean onlyNotEmpty ) 15 | throws Exception 16 | { 17 | return getConnection( bean.getUrl(), bean.getUser(), bean.getPassword(), onlyNotEmpty ); 18 | } 19 | 20 | public static DBConnection getConnection( String url, String usr, String pass, boolean onlyNotEmpty ) 21 | throws Exception 22 | { 23 | DBConnection con = null; 24 | if( url.startsWith( "jdbc:" ) ) 25 | { 26 | con = new JDBCConnection( url, usr, pass, onlyNotEmpty ); 27 | } 28 | else if( url.startsWith( "jackcess:" ) ) 29 | { 30 | con = new JackcessConnection( url, usr, pass, onlyNotEmpty ); 31 | } 32 | else if( url.startsWith( "dummy:" ) ) 33 | { 34 | con = new DummyConnection( url, usr, pass, onlyNotEmpty ); 35 | } 36 | if( con == null ) 37 | { 38 | System.out.println( "Couldn't get connection for URL: " + url ); 39 | } 40 | return con; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/beans/ForeignKeyDefinition.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.beans; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import pt.evolute.dbtransfer.constrain.Constrainer; 7 | import pt.evolute.dbtransfer.db.helper.HelperManager; 8 | 9 | public class ForeignKeyDefinition 10 | { 11 | private static final boolean honorNames; 12 | static 13 | { 14 | honorNames = "true".equals( HelperManager.getProperties().get( Constrainer.CONSTRAIN_KEEP_NAMES ) ); 15 | } 16 | 17 | public final Name table; 18 | public final String name; 19 | public final List columns = new ArrayList(); 20 | 21 | public String outputName = null; 22 | 23 | public ForeignKeyDefinition( String n, Name t ) 24 | { 25 | name = n; 26 | table = t; 27 | } 28 | 29 | public String getOutputName() 30 | { 31 | if( outputName == null ) 32 | { 33 | if( honorNames && name != null && !name.isEmpty() ) 34 | { 35 | outputName = name; 36 | } 37 | else 38 | { 39 | outputName = table.saneName + "_"; 40 | for( ColumnDefinition col: columns ) 41 | { 42 | outputName += col.name.saneName + "_" + col.referencedTable.saneName + "_" + col.referencedColumn.name.saneName + "_"; 43 | } 44 | outputName += "fk"; 45 | } 46 | } 47 | return outputName; 48 | } 49 | 50 | public String getOriginalName() 51 | { 52 | return name; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/diff/CachedDBView.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.diff; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import pt.evolute.dbtransfer.db.DBConnection; 7 | import pt.evolute.dbtransfer.db.PrimaryKeyValue; 8 | import pt.evolute.utils.dbmodel.DBTable; 9 | 10 | public class CachedDBView { 11 | private final int ROWS; 12 | // private final DBTable TABLE; 13 | // private final DBConnection CONNECTION; 14 | // private final Boolean GET_ACTION; 15 | private final Map MAP = new HashMap(); 16 | 17 | private PrimaryKeyValue minLoadedKey = null; 18 | private PrimaryKeyValue maxLoadedKey = null; 19 | 20 | private boolean loadedAll = false; 21 | 22 | public CachedDBView( int rows, DBTable table, DBConnection conn, boolean getAction ) 23 | { 24 | ROWS = rows; 25 | // TABLE = table; 26 | // CONNECTION = conn; 27 | // GET_ACTION = getAction; 28 | } 29 | 30 | public TableRow get( PrimaryKeyValue key ) 31 | { 32 | if( !loadedAll 33 | && ( key.compareTo( minLoadedKey ) < 0 34 | || key.compareTo( maxLoadedKey ) > 0 ) ) 35 | { 36 | loadRows(); 37 | } 38 | TableRow row = MAP.get( key ); 39 | if( row == null ) 40 | { 41 | 42 | } 43 | return row; 44 | } 45 | 46 | private void loadRows() { 47 | MAP.clear(); 48 | 49 | 50 | 51 | if( MAP.size() != ROWS ) 52 | { 53 | loadedAll = true; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/dbmodel/DBColumn.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.dbmodel; 2 | 3 | import pt.evolute.utils.object.DefaultLightPropertyObject; 4 | import pt.evolute.utils.tables.ColumnizedObject; 5 | 6 | 7 | /** 8 | * 9 | * @author lflores 10 | */ 11 | public class DBColumn extends DefaultLightPropertyObject 12 | implements ColumnizedObject, Cloneable 13 | { 14 | public static final String TABLE = "TABLE"; 15 | public static final String NAME = "NAME"; 16 | public static final String TYPE = "TYPE"; 17 | public static final String TYPE_ID = "TYPE_ID"; 18 | public static final String LENGTH = "LENGTH"; 19 | public static final String IS_FOREIGN_KEY = "IS_FOREIGN_KEY"; 20 | public static final String IS_PRIMARY_KEY = "IS_PRIMARY_KEY"; 21 | 22 | public DBColumn() 23 | { 24 | super( new String[] { TABLE, NAME, TYPE, TYPE_ID, LENGTH, IS_FOREIGN_KEY, IS_PRIMARY_KEY }, true ); 25 | } 26 | 27 | @SuppressWarnings("unchecked") 28 | public Object getValue( int col ) 29 | { 30 | return get( getPropertyNames()[ col ] ); 31 | } 32 | 33 | @Override 34 | public Object clone() 35 | { 36 | DBColumn column = new DBColumn(); 37 | column.setMapData( getMapData() ); 38 | return column; 39 | } 40 | @Override 41 | public String toString() 42 | { 43 | return ( String ) get( NAME ) + " PK: " + get( IS_PRIMARY_KEY ) + " FK: " + get( IS_FOREIGN_KEY );// + " - " + hashCode(); 44 | } 45 | 46 | public Integer getType() 47 | { 48 | return (Integer)getValue( 3 ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLConcat.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | 6 | public class SQLConcat extends SQLFunction 7 | { 8 | protected Operand parameters[]; 9 | 10 | public SQLConcat( Operand parameters[] ) 11 | { 12 | super( "CONCAT" ); 13 | this.parameters = parameters; 14 | if( this.parameters != null ) 15 | { 16 | for( int p = 0; p < this.parameters.length; p++ ) 17 | { 18 | this.parameters[ p ] = new SQLCast( this.parameters[ p ], "VARCHAR" ); 19 | } 20 | } 21 | } 22 | 23 | public SQLConcat( Operand parameter ) 24 | { 25 | this( parameter != null ? new Operand[]{ parameter } : null ); 26 | } 27 | 28 | @Override 29 | public String getSymbol() 30 | { 31 | return "" + getBackend().getUserFunctionName( this ); 32 | } 33 | 34 | @Override 35 | public String toString() 36 | { 37 | String str = ""; 38 | if( parameters != null && parameters.length > 0 ) 39 | { 40 | str += parameters[ 0 ]; 41 | for( int n = 1; n < parameters.length; n++ ) 42 | { 43 | str += getSymbol() + parameters[ n ]; 44 | } 45 | } 46 | return str; 47 | } 48 | 49 | @Override 50 | public void setBackend( Backend backend ) 51 | { 52 | super.setBackend( backend ); 53 | if( parameters != null ) 54 | { 55 | for( Operand parameter : parameters ) 56 | { 57 | parameter.setBackend( backend ); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/dummy/Dummy2DArray.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.dummy; 2 | 3 | import pt.evolute.utils.arrays.Virtual2DArray; 4 | import pt.evolute.utils.arrays.exception.EndOfArrayException; 5 | 6 | /** 7 | * 8 | * @author lflores 9 | */ 10 | public class Dummy2DArray implements Virtual2DArray 11 | { 12 | private final int ROWS; 13 | private final String COLUMNS[]; 14 | 15 | public Dummy2DArray( int rows, String cols[] ) 16 | { 17 | ROWS = rows; 18 | COLUMNS = cols; 19 | } 20 | 21 | @SuppressWarnings("unchecked") 22 | @Override 23 | public Long get(int r, int c) 24 | { 25 | if( r >= ROWS ) 26 | { 27 | throw new EndOfArrayException(); 28 | } 29 | return ( long )r; 30 | } 31 | 32 | public void set(int i, int i1, Object o) 33 | { 34 | throw new UnsupportedOperationException("Not supported yet."); 35 | } 36 | 37 | public int rowLength() 38 | { 39 | return columnCount(); 40 | } 41 | 42 | public int columnCount() 43 | { 44 | return COLUMNS.length; 45 | } 46 | 47 | public int columnLength() 48 | { 49 | return rowCount(); 50 | } 51 | 52 | public int rowCount() 53 | { 54 | return ROWS; 55 | } 56 | 57 | public Object[][] getObjects() 58 | { 59 | throw new UnsupportedOperationException("Not supported yet."); 60 | } 61 | 62 | public void deleteRow(int i) 63 | { 64 | throw new UnsupportedOperationException("Not supported yet."); 65 | } 66 | 67 | public void appendEmptyRow() 68 | { 69 | throw new UnsupportedOperationException("Not supported yet."); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/Field.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql; 2 | 3 | import pt.evolute.utils.sql.backend.Backend; 4 | import pt.evolute.utils.sql.table.DefaultTable; 5 | import pt.evolute.utils.sql.table.Table; 6 | 7 | public class Field extends Operand 8 | { 9 | private final String iName; 10 | private final Table iTable; 11 | 12 | public static Field createNewField( String name ) 13 | { 14 | return new Field(name); 15 | } 16 | 17 | public static Field createNewField( String name, Table table ) 18 | { 19 | return new Field( name, table ); 20 | } 21 | 22 | public static Field createNewField( String name, String tablename ) 23 | { 24 | return new Field( name, tablename ); 25 | } 26 | 27 | public Field( String name ) 28 | { 29 | this( name, ( Table )null ); 30 | } 31 | 32 | public Field( String name, Table table ) 33 | { 34 | super( name ); 35 | iName = name; 36 | iTable = table; 37 | } 38 | 39 | public Field( String column, String tablename ) 40 | { 41 | this( column, new DefaultTable( tablename ) ); 42 | } 43 | 44 | public String getName() 45 | { 46 | return iName; 47 | } 48 | 49 | public Assignment assign( Object value ) 50 | { 51 | return new Assignment( this, value ); 52 | } 53 | 54 | @Override 55 | public String toString() 56 | { 57 | return ( iTable != null ? iTable.toString() + "." : "" ) + getEscapedName( getBackend() ); 58 | } 59 | 60 | private CharSequence getEscapedName( Backend backend ) 61 | { 62 | return backend.getEscapedFieldName( getName() ); 63 | } 64 | 65 | public Table getTable() 66 | { 67 | return iTable; 68 | } 69 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/Between.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import pt.evolute.utils.sql.Condition; 4 | import pt.evolute.utils.sql.Operand; 5 | /** 6 | * 7 | * @author fpalma 8 | */ 9 | public class Between extends Condition 10 | { 11 | private String leftStr = null; 12 | private String rightStr = null; 13 | private Operand right; 14 | 15 | /** Creates a new instance of Between */ 16 | public Between( Operand left, Operand right ) 17 | { 18 | super( left, right ); 19 | this.right = right; 20 | } 21 | 22 | @Override 23 | public String getSymbol() 24 | { 25 | return "BETWEEN"; 26 | } 27 | 28 | @Override 29 | public String getLeft() 30 | { 31 | if( leftStr == null ) 32 | { 33 | leftStr = super.getLeft(); 34 | return leftStr; 35 | } 36 | else 37 | { 38 | return leftStr; 39 | } 40 | } 41 | 42 | @Override 43 | public String getRight() 44 | { 45 | if( rightStr == null ) 46 | { 47 | right.setBackend( getBackend() ); 48 | Object []array = right.getInnerData(); 49 | if( array == null || array.length != 2) 50 | { 51 | rightStr = ""; 52 | } 53 | else 54 | { 55 | Operand first = array[ 0 ] instanceof Operand ? ( Operand )array[ 0 ] : new Operand( array[ 0 ] ); 56 | first.setBackend( getBackend() ); 57 | Operand second = array[ 1 ] instanceof Operand ? ( Operand )array[ 1 ] : new Operand( array[ 1 ] ); 58 | second.setBackend( getBackend() ); 59 | rightStr = first + " AND " + second; 60 | } 61 | return rightStr; 62 | } 63 | else 64 | { 65 | return rightStr; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/helper/HelperManager.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.helper; 2 | 3 | import java.util.Properties; 4 | 5 | public class HelperManager 6 | { 7 | private static Properties properties = null; 8 | 9 | public static Helper getTranslator( String url ) 10 | { 11 | Helper tr = null; 12 | if( url.startsWith( "jdbc:sqlserver:" ) ) 13 | { 14 | System.out.println( "SQL Server translator" ); 15 | tr = SQLServerHelper.getTranslator(); 16 | } 17 | else if( url.startsWith( "jdbc:postgresql:" ) ) 18 | { 19 | System.out.println( "PostgreSQL translator" ); 20 | tr = PostgreSQLServerHelper.getTranslator(); 21 | } 22 | else if( url.startsWith( "jdbc:mysql:" ) ) 23 | { 24 | System.out.println( "MySQL translator" ); 25 | tr = MySQLServerHelper.getTranslator(); 26 | } 27 | else if( url.startsWith( "jdbc:oracle:" ) ) 28 | { 29 | System.out.println( "Oracle translator" ); 30 | tr = OracleServerHelper.getTranslator(); 31 | } 32 | else if( url.startsWith( "jdbc:hsqldb:" ) ) 33 | { 34 | System.out.println( "HsqlDB translator" ); 35 | tr = OracleServerHelper.getTranslator(); 36 | } 37 | else if( url.startsWith( "jdbc:ucanaccess:" ) ) 38 | { 39 | System.out.println( "HsqlDB translator" ); 40 | tr = HsqlDBServerHelper.getTranslator(); 41 | } 42 | if( tr == null ) 43 | { 44 | System.out.println( "Default translator" ); 45 | tr = NullHelper.getTranslator(); 46 | } 47 | return tr; 48 | } 49 | 50 | public static void setProperties( Properties props ) 51 | { 52 | properties = props; 53 | } 54 | 55 | public static Properties getProperties() 56 | { 57 | return properties; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/dbmodel/DBHierarchy.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.dbmodel; 2 | 3 | import java.util.List; 4 | import java.util.Vector; 5 | 6 | import pt.evolute.utils.object.DefaultLightPropertyObject; 7 | import pt.evolute.utils.tables.ColumnizedObject; 8 | 9 | /** 10 | * 11 | * @author lflores 12 | */ 13 | public class DBHierarchy extends DefaultLightPropertyObject 14 | implements ColumnizedObject 15 | { 16 | public static final String SRC_TABLE = "SRC_TABLE"; 17 | 18 | // private final ModelProvider provider; 19 | 20 | private List tableList = new Vector(); 21 | private String tableListStr = null; 22 | 23 | /** Creates a new instance of DBHierarchy */ 24 | public DBHierarchy( ModelProvider provider ) 25 | { 26 | super( new String[] { SRC_TABLE }, false ); 27 | // this.provider = provider; 28 | } 29 | 30 | public void addTable( DBTable table ) 31 | { 32 | tableList.add( table ); 33 | tableListStr = null; 34 | } 35 | 36 | public void addReverseTable( DBTable table ) 37 | { 38 | tableList.add( 0, table ); 39 | tableListStr = null; 40 | } 41 | 42 | @SuppressWarnings("unchecked") 43 | public Object getValue( int col ) 44 | { 45 | if( tableListStr == null ) 46 | { 47 | StringBuffer buffer = new StringBuffer( ( String )tableList.get( tableList.size() - 1 ).get( DBTable.NAME ) ); 48 | for( int i = tableList.size() - 2; i >= 0 ; --i ) 49 | { 50 | buffer.append( " -> " ); 51 | buffer.append( tableList.get( i ).get( DBTable.NAME ) ); 52 | } 53 | tableListStr = buffer.toString(); 54 | } 55 | return tableListStr; 56 | } 57 | 58 | public DBTable[] getTables() 59 | { 60 | return tableList.toArray( new DBTable[ tableList.size() ] ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/diff/TableRow.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.diff; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import pt.evolute.dbtransfer.db.PrimaryKeyValue; 7 | 8 | public class TableRow 9 | { 10 | private static final String STATUS_INSERTED = "i"; 11 | private static final String STATUS_UPDATED = "u"; 12 | private static final String STATUS_DELETED = "d"; 13 | 14 | private String status = null; 15 | private String rowMd5 = null; 16 | public final List row = new ArrayList(); 17 | 18 | private void updateMd5() 19 | { 20 | StringBuilder sb = new StringBuilder( "*" ); 21 | for( Object o: row ) 22 | { 23 | if( o == null ) 24 | { 25 | sb.append( "null" ); 26 | } 27 | else if( o instanceof java.sql.Date ) 28 | { 29 | sb.append( PrimaryKeyValue.D_F.format( o ) ); 30 | } 31 | else if( o instanceof java.sql.Time ) 32 | { 33 | sb.append( PrimaryKeyValue.T_F.format( o ) ); 34 | } 35 | else if( o instanceof java.sql.Timestamp ) 36 | { 37 | sb.append( PrimaryKeyValue.TS_F.format( o ) ); 38 | } 39 | else 40 | { 41 | sb.append( o ); 42 | } 43 | sb.append( "*" ); 44 | } 45 | rowMd5 = sb.toString(); 46 | } 47 | 48 | public String getMd5() 49 | { 50 | if( rowMd5 == null ) 51 | { 52 | updateMd5(); 53 | } 54 | return rowMd5; 55 | } 56 | 57 | public boolean isDeleted() 58 | { 59 | return STATUS_DELETED.equals( status ); 60 | } 61 | 62 | public void setStatus( String s ) 63 | throws Exception 64 | { 65 | if( !STATUS_INSERTED.equals( s ) 66 | && !STATUS_UPDATED.equals( s ) 67 | && !STATUS_DELETED.equals( s )) 68 | { 69 | throw new Exception( "Invalid status for row: " + s ); 70 | } 71 | status = s; 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/DBConnection.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.util.List; 5 | 6 | import pt.evolute.dbtransfer.db.beans.ColumnDefinition; 7 | import pt.evolute.dbtransfer.db.beans.ForeignKeyDefinition; 8 | import pt.evolute.dbtransfer.db.beans.PrimaryKeyDefinition; 9 | import pt.evolute.dbtransfer.db.beans.TableDefinition; 10 | import pt.evolute.dbtransfer.db.beans.UniqueDefinition; 11 | import pt.evolute.dbtransfer.db.helper.Helper; 12 | import pt.evolute.utils.arrays.Virtual2DArray; 13 | import pt.evolute.utils.dbmodel.DBTable; 14 | 15 | /** 16 | * 17 | * @author lflores 18 | */ 19 | public interface DBConnection 20 | { 21 | public List getTableList() 22 | throws Exception; 23 | 24 | public List getColumnList(TableDefinition table) 25 | throws Exception; 26 | 27 | public PrimaryKeyDefinition getPrimaryKey(TableDefinition table) 28 | throws Exception; 29 | 30 | public List getForeignKeyList(TableDefinition table) 31 | throws Exception; 32 | 33 | public Virtual2DArray getFullTable(TableDefinition table) 34 | throws Exception; 35 | 36 | public Virtual2DArray executeQuery(String sql) 37 | throws Exception; 38 | 39 | public PreparedStatement prepareStatement(String sql) 40 | throws Exception; 41 | 42 | public List getSortedTables() 43 | throws Exception; 44 | 45 | public List getUniqueList(TableDefinition table) 46 | throws Exception; 47 | 48 | public int getRowCount(TableDefinition table) 49 | throws Exception; 50 | 51 | public Helper getHelper(); 52 | 53 | public void addColumnToTable(TableDefinition table, ColumnDefinition col) throws Exception; 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/function/SQLDistinct.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.function; 2 | 3 | import pt.evolute.utils.sql.Operand; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | 6 | /** 7 | * 8 | * @author fpalma 9 | */ 10 | public class SQLDistinct extends SQLFunction 11 | { 12 | protected Operand parameter; 13 | protected Operand parameters[]; 14 | 15 | /** Creates a new instance of SQLDistinct */ 16 | public SQLDistinct(Operand parameter) 17 | { 18 | super( "DISTINCT" ); 19 | this.parameter = parameter; 20 | } 21 | 22 | public SQLDistinct(Object parameters[]) 23 | { 24 | super( "DISTINCT" ); 25 | this.parameters = new Operand[ parameters.length ]; 26 | for( int n = 0; n < parameters.length; n++ ) 27 | { 28 | this.parameters[ n ] = new Operand( parameters[ n ] ); 29 | } 30 | } 31 | 32 | public SQLDistinct(Operand parameters[]) 33 | { 34 | super( "DISTINCT" ); 35 | this.parameters = parameters; 36 | } 37 | 38 | @Override 39 | public String getSymbol() 40 | { 41 | return "DISTINCT "; 42 | } 43 | 44 | @Override 45 | public String toString() 46 | { 47 | if( parameters == null || parameters.length == 0 ) 48 | { 49 | return "DISTINCT " + parameter; 50 | } 51 | else 52 | { 53 | String str = "DISTINCT " + parameters[ 0 ]; 54 | 55 | for( int n = 1; n < parameters.length; n++ ) 56 | { 57 | str += ", " + parameters[ n ]; 58 | } 59 | return str; 60 | } 61 | } 62 | 63 | @Override 64 | public void setBackend( Backend backend ) 65 | { 66 | super.setBackend( backend ); 67 | if( parameter != null ) 68 | { 69 | parameter.setBackend( backend ); 70 | } 71 | if( parameters != null && parameters.length > 0 ) 72 | { 73 | for( Operand p: parameters ) 74 | { 75 | p.setBackend( backend ); 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /vs_pgloader.io.txt: -------------------------------------------------------------------------------- 1 | dbtransfer vs pgloader.io 2 | 3 | Aims 4 | dbtransfer: 5 | transfer data between jdbc data sources, with support for mdb (MS Access files) sources as fast as possible 6 | 7 | pgloader.io 8 | load data from a few selected sources to postgresql as fast as possible 9 | 10 | Data source support 11 | dbtransfer: 12 | any jdbc data source support plus mdb files, some data sources have advanced support, meaning some required 13 | casts are natively detected by dbtransfer (mdb,oracle,mssql,mysql,pgsql) 14 | 15 | pgloader.io: 16 | only csv,mysql,mssql,dbf,fixed,sqlite,db3,ixf,copy are supported, but support is more complete than dbtransfer 17 | 18 | Destination support 19 | dbtransfer: 20 | any jdbc data source, with advanced support for mdb,oracle,mssql,mysql,pgsql. 21 | pgsql is the destination better supported on dbtransfer, but uses same protocol (jdbc/SQL) as the others 22 | 23 | pgloader.io: 24 | pgsql, only destination supported, uses specific (COPY) pgsql funcionality to achieve higher insert rates 25 | 26 | Architecture 27 | dbtransfer: 28 | really multi-threaded. dbtransfer always uses one reader and one writer threads, with a FIFO between. 29 | however we can enable as many transfer threads as we like, and dbtransfer will use N readers and N writers, 30 | one per table, it transfers tables concurrently, because some tables have faster reads and others have faster writes, 31 | and a FIFO is not enough to have both systems (source and destiny) at full speed, 32 | parallel table transfer is a more complete aproach 33 | data insert is done in bulk inserts (1k rows) using prepared statements and plain SQL 34 | 35 | pgloader.io: 36 | multi-threaded, one reader, FIFO, one writer 37 | data insert is done using pgsql COPY protocol, is really, really fast 38 | 39 | 40 | PS: Hello Dimitri Fontaine, feel free to complete or correct this comparison 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DBTransfer 2 | ========== 3 | 4 | **[DBTransfer](http://dbtransfer.evo.pt/)** - versatile and fast database transfer tool 5 | 6 | ## What is DBTransfer? 7 | DBTransfer is a multi-platform java tool, that aims to replicate one 8 | database (JDBC or MS Access) to another (JDBC), using an one to one 9 | conversion. 10 | 11 | ## What can I do with DBTransfer? 12 | - Copy data from one database type to another type. Example: you can 13 | migrate your MSSQL to PostgreSQL, without losing the structure, 14 | including not only the original schema, the constraints, and of course, 15 | the data it self, which is converted to respective data-type. 16 | - Copy one database schema to another. 17 | - Move data from one database to another. 18 | - Compare two databases. 19 | 20 | ## Downloading and running DBTransfer 21 | For now you, to run DBTransfer, you need to check out the project, and 22 | compile it, using: 23 | - mvn package 24 | 25 | This will create a ./target/dbtransfer-1.0-SNAPSHOT.jar 26 | 27 | After this, you have to run the tool, using: 28 | 29 | - java -jar dbtransfer-1.0-SNAPSHOT.jar _**dbtransfer.properties**_ 30 | 31 | You have to create a properties file, like the ones in the examples. 32 | 33 | ## What needs to be done.. right away! 34 | Improve the output, ~~and enable Maven~~ on the project. Feel free to help 35 | out! 36 | 37 | ## Sponsors 38 | This project had the invaluable help of a tool, DBVisualizer, which help 39 | us test everything and connect to any database. DBVisualizer uses JDBC, the same framework as DBTransfer, so it provides a nice way to validate database metadata and testing database connections to use in the properties file. 40 | 41 | Our friends at DBVisualizer were very kind to provide to all the 42 | contributers, a valid DBVisualzer Pro license. Thank you for your 43 | support! 44 | 45 | DBVisualizer - http://www.dbvis.com 46 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/beans/ConnectionDefinitionBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | package pt.evolute.dbtransfer.db.beans; 8 | 9 | import java.util.Arrays; 10 | import java.util.Properties; 11 | 12 | /** 13 | * 14 | * @author lflores 15 | */ 16 | public class ConnectionDefinitionBean 17 | { 18 | private final String url; 19 | private final String user; 20 | private final String passwd; 21 | private final String schema; 22 | 23 | public ConnectionDefinitionBean( String jdbcUrl, String usr, String pass, String dbSchema ) 24 | { 25 | url = jdbcUrl; 26 | user = usr; 27 | passwd = pass; 28 | schema = dbSchema; 29 | } 30 | 31 | public String getUrl() 32 | { 33 | return url; 34 | } 35 | 36 | public String getUser() 37 | { 38 | return user; 39 | } 40 | 41 | public String getPassword() 42 | { 43 | return passwd; 44 | } 45 | 46 | public String getSchema() 47 | { 48 | return schema; 49 | } 50 | 51 | public String toString() 52 | { 53 | return "URL: " + url + " user: " + user + " schema: " + schema; 54 | } 55 | 56 | public static ConnectionDefinitionBean loadBean( Properties props, String pro[] ) 57 | { 58 | if( pro == null || ( pro.length != 4 && pro.length != 5 ) ) 59 | { 60 | throw new RuntimeException( "pro[] must be not null and have 4 or 5 elements + " + Arrays.asList( pro ) ); 61 | } 62 | return new ConnectionDefinitionBean( props.getProperty( pro[ 0 ] ), 63 | props.getProperty( pro[ 1 ] ), props.getProperty( pro[ 2 ] ), 64 | props.getProperty( pro[ 3 ] ) ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/diff/TablePage.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.diff; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.Set; 8 | 9 | import pt.evolute.dbtransfer.db.PrimaryKeyValue; 10 | 11 | public class TablePage 12 | { 13 | private PrimaryKeyValue pkvFirst = null; 14 | private PrimaryKeyValue pkvLast = null; 15 | private final Map map = new HashMap(); 16 | private final List keys = new LinkedList(); 17 | 18 | public void put( PrimaryKeyValue pkv, TableRow row ) 19 | { 20 | if( pkvFirst == null ) 21 | { 22 | pkvFirst = pkv; 23 | } 24 | map.put( pkv, row ); 25 | pkvLast = pkv; 26 | keys.add( pkv ); 27 | } 28 | 29 | public TableRow get( PrimaryKeyValue pkv ) 30 | { 31 | return map.get( pkv ); 32 | } 33 | 34 | public PrimaryKeyValue getFirst() 35 | { 36 | return pkvFirst; 37 | } 38 | 39 | public PrimaryKeyValue getLast() 40 | { 41 | return pkvLast; 42 | } 43 | 44 | public List allKeysOrdered() 45 | { 46 | return keys; 47 | } 48 | 49 | public Set keySet() 50 | { 51 | return map.keySet(); 52 | } 53 | 54 | public boolean isPrimaryKeyValueInsidePage( PrimaryKeyValue pkv ) 55 | { 56 | // System.out.println( "pkvFirst: " + pkvFirst + " pkvLast: " + pkvLast + " pkv? " + pkv + " inside: " + ( pkvFirst != null && pkvFirst.compareTo( pkv ) <= 0 && pkvLast.compareTo( pkv ) >= 0 ) ); 57 | return pkvFirst != null && pkvFirst.compareTo( pkv ) <= 0 && pkvLast.compareTo( pkv ) >= 0; 58 | } 59 | 60 | public int size() 61 | { 62 | return keys.size(); 63 | } 64 | 65 | public boolean containsKey( PrimaryKeyValue pkv ) 66 | { 67 | return map.containsKey( pkv ); 68 | } 69 | 70 | public TableRow remove( PrimaryKeyValue pkv ) 71 | { 72 | return map.remove( pkv ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/Expression.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql; 2 | 3 | import pt.evolute.utils.error.ErrorLogger; 4 | import pt.evolute.utils.sql.backend.Backend; 5 | import pt.evolute.utils.sql.expression.And; 6 | import pt.evolute.utils.sql.expression.Or; 7 | 8 | public abstract class Expression 9 | { 10 | protected final Condition iCondition; 11 | protected final Expression iLeft; 12 | protected final Expression iRight; 13 | 14 | protected Backend backend = null; 15 | 16 | protected boolean unicode = false; 17 | 18 | public Expression( Condition cond ) 19 | { 20 | iCondition = cond; 21 | iLeft = null; 22 | iRight = null; 23 | } 24 | 25 | public Expression( Expression left, Expression right ) 26 | { 27 | iCondition = null; 28 | iLeft = left; 29 | iRight = right; 30 | } 31 | 32 | @Override 33 | public String toString() 34 | { 35 | if( iCondition != null ) 36 | { 37 | iCondition.setBackend( backend ); 38 | } 39 | return "( " + getLeft() + " " + getSymbol() + " " + getRight() + " )"; 40 | } 41 | 42 | public String getLeft() 43 | { 44 | iLeft.setBackend( backend ); 45 | return iLeft.toString(); 46 | } 47 | 48 | public String getRight() 49 | { 50 | String right = null; 51 | if( iRight != null ) 52 | { 53 | iRight.setBackend( backend ); 54 | right = iRight.toString(); 55 | } 56 | else 57 | { 58 | ErrorLogger.logException( new Exception( "NULL right expression!!! getSymbol: " 59 | + getSymbol() + " left: " + getLeft() ) ); 60 | right = " TRUE "; 61 | } 62 | return right; 63 | } 64 | 65 | public abstract String getSymbol(); 66 | 67 | public And and( Expression other ) 68 | { 69 | return new And( this, other ); 70 | } 71 | 72 | public Or or( Expression other ) 73 | { 74 | return new Or( this, other ); 75 | } 76 | 77 | public void setBackend( Backend backend ) 78 | { 79 | this.backend = backend; 80 | } 81 | 82 | public void setUnicode( boolean translate ) 83 | { 84 | unicode = translate; 85 | } 86 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/helper/Helper.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.helper; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.SQLException; 5 | import java.sql.Statement; 6 | 7 | import pt.evolute.dbtransfer.db.DBConnection; 8 | import pt.evolute.dbtransfer.db.beans.Name; 9 | 10 | public interface Helper 11 | { 12 | public String outputType(String type, Integer size); 13 | 14 | public String outputName(String type); 15 | 16 | public String normalizedType(String type); 17 | 18 | public String preLoadSetup(String table); 19 | 20 | public String postLoadSetup(String table); 21 | 22 | public void fixSequences(DBConnection con, String table, String typeName, String column) 23 | throws Exception; 24 | 25 | public void setDefaultValue(DBConnection con, String table, String typeName, String column, String value) 26 | throws Exception; 27 | 28 | public void setNotNull(DBConnection con, String table, String typeName, String column, Integer size) 29 | throws Exception; 30 | 31 | public String normalizeValue(String value); 32 | 33 | public String outputValue(String value); 34 | 35 | public Object outputValue(Object value); 36 | 37 | public int translateType(int type); 38 | 39 | public String getParametersHelp(); 40 | 41 | public String normalizeDefault(String string); 42 | 43 | public void setPreparedValue(PreparedStatement pStm, int col, Object o, int type) throws SQLException; 44 | 45 | public void setupStatement(Statement stm) throws SQLException; 46 | 47 | public void initConnection( DBConnection con) 48 | throws Exception; 49 | 50 | public boolean isTableValid(Name n); 51 | 52 | public String getDropTable( String table ); 53 | 54 | public String getBegin(); 55 | 56 | public String getCommit(); 57 | 58 | public String getRollback(); 59 | 60 | public String getCreateTablePrefix(); 61 | 62 | public String getType(); 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/jdbc/StatementExecuterFactory.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.jdbc; 2 | 3 | import pt.evolute.utils.arrays.Virtual2DArray; 4 | import pt.evolute.utils.sql.SQLQuery; 5 | 6 | public class StatementExecuterFactory 7 | { 8 | private static StatementExecuter executer = null; 9 | 10 | // default initialization 11 | static 12 | { 13 | // executer = new DALStatementExecuter(); 14 | } 15 | 16 | public static boolean isInitialized() 17 | { 18 | return executer != null; 19 | } 20 | 21 | public static void initialize( StatementExecuter exe ) 22 | { 23 | executer = exe; 24 | } 25 | 26 | public static Virtual2DArray executeSelectStatementWithCursor( String stm, SQLQuery query ) 27 | throws Exception 28 | { 29 | if( executer == null ) 30 | { 31 | throw new Exception( "StatementExecuterFactory: StatementExecuter is null\n" + 32 | stm + "\n" + query ); 33 | } 34 | return executer.executeSelectStatementWithCursor( stm, query ); 35 | } 36 | 37 | 38 | public static Virtual2DArray executeUpdateStatementWithCursor( String stm, SQLQuery query ) 39 | throws Exception 40 | { 41 | if( executer == null ) 42 | { 43 | throw new Exception( "StatementExecuterFactory: StatementExecuter is null\n" + 44 | stm + "\n" + query ); 45 | } 46 | return executer.executeUpdateStatementWithCursor( stm, query ); 47 | } 48 | 49 | public static Object[][] executeSelectStatement( String stm, SQLQuery query ) 50 | throws Exception 51 | { 52 | if( executer == null ) 53 | { 54 | throw new Exception( "StatementExecuterFactory: StatementExecuter is null\n" + 55 | stm + "\n" + query ); 56 | } 57 | return executer.executeSelectStatement( stm, query ); 58 | } 59 | 60 | public static Object[][] executeUpdateStatement( String stm, SQLQuery query ) 61 | throws Exception 62 | { 63 | if( executer == null ) 64 | { 65 | throw new Exception( "StatementExecuterFactory: StatementExecuter is null\n" + 66 | stm + "\n" + query ); 67 | } 68 | return executer.executeUpdateStatement( stm, query ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/backend/Backend.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.backend; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import java.util.List; 6 | 7 | import pt.evolute.utils.ddl.DDLDefaultValue; 8 | import pt.evolute.utils.sql.Expression; 9 | import pt.evolute.utils.sql.Select2; 10 | import pt.evolute.utils.sql.function.SQLFunction; 11 | 12 | public interface Backend 13 | { 14 | public void config(Connection con); 15 | 16 | public String[] getInitQuery(); 17 | 18 | public CharSequence getEscapedFieldName(CharSequence name); 19 | 20 | public CharSequence getLimitFieldsPrefix(int limit); 21 | 22 | public CharSequence getLimitQuerySuffix(int limit); 23 | 24 | public CharSequence getOffsetQueryPrefix(Select2 query); 25 | 26 | public CharSequence getOffsetQuerySuffix(int offset); 27 | 28 | public String getBoolean(boolean bool); 29 | 30 | public String getBegin(); 31 | 32 | public CharSequence getUserFunctionPrefix(); 33 | 34 | public CharSequence getUserFunctionName(SQLFunction fun); 35 | 36 | public CharSequence portSyntax(CharSequence query); 37 | 38 | public void setEscapeUnicode(boolean escapeUnicode); 39 | 40 | public boolean getEscapeUnicode(); 41 | 42 | public CharSequence escapeUnicode(CharSequence str); 43 | 44 | public String getDDLConstraintDefinitionPrefix(); 45 | 46 | public String getDDLCheckConstraint(Expression expression); 47 | 48 | public String getDDLUniqueConstraint(List fieldNames); 49 | 50 | public String getDDLDefaultValueConstraint(String fieldName, DDLDefaultValue defaultValue); 51 | 52 | public String getDDLPrimaryKeyConstraint(List fieldNames); 53 | 54 | public String getDDLForeignKeyConstraint(List fieldNames, String foreignTableName, List foreignFieldNames); 55 | 56 | public boolean getDDLDefaultValueIsConstraint(); 57 | 58 | public boolean supportsILike(); 59 | 60 | public boolean supportsReturnGeneratedKeys(); 61 | 62 | // public String getKeepAliveQuery(); 63 | 64 | public boolean isValid(Connection con) 65 | throws SQLException; 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/arrays/IntArrayIntervalFinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ArrayIntervalFinder.java 3 | * 4 | * Created on 21 de Marco de 2005, 17:49 5 | */ 6 | 7 | package pt.evolute.utils.arrays; 8 | 9 | import java.util.LinkedList; 10 | import java.util.List; 11 | 12 | /** 13 | * 14 | * @author fpalma 15 | */ 16 | public class IntArrayIntervalFinder 17 | { 18 | public static final int DEFAULT_MIN_INTERVAL = 4; 19 | 20 | // public static Vector find( int array[] ) 21 | // { 22 | // 23 | // } 24 | 25 | public static List findIntervals( Integer array[] ) 26 | { 27 | return findIntervals( array, DEFAULT_MIN_INTERVAL ); 28 | } 29 | 30 | public static List findIntervals( Integer array[], int minInterval ) 31 | { 32 | List v = new LinkedList(); 33 | List isolated = new LinkedList(); 34 | if( array == null || array.length == 0 ) 35 | { 36 | return v; 37 | } 38 | Integer last = null; 39 | int count = 0; 40 | for( int n = 0; n < array.length; n++ ) 41 | { 42 | if( last == null ) 43 | { 44 | last = array[ n ]; 45 | count = 1; 46 | continue; 47 | } 48 | if( array[ n ].intValue() == array[ n - 1 ].intValue() + 1 ) 49 | { 50 | count++; 51 | } 52 | else if( count == 1 ) 53 | { 54 | isolated.add( last ); 55 | last = array[ n ]; 56 | } 57 | else if( count < minInterval ) 58 | { 59 | for( int i = 0; i < count; i++ ) 60 | { 61 | isolated.add( last.intValue() + i ); 62 | } 63 | count = 1; 64 | last = array[ n ]; 65 | } 66 | else 67 | { 68 | v.add( new Integer[]{ last, array[ n - 1 ] } ); 69 | count = 1; 70 | last = array[ n ]; 71 | } 72 | } 73 | if( count == 1 ) 74 | { 75 | isolated.add( last ); 76 | } 77 | else if( count < minInterval ) 78 | { 79 | for( int i = 0; i < count; i++ ) 80 | { 81 | isolated.add( last.intValue() + i ); 82 | } 83 | } 84 | else 85 | { 86 | v.add( new Integer[]{ last, array[ array.length - 1 ] } ); 87 | } 88 | // if( isolated.size() > 0 ) 89 | // { 90 | v.add( isolated.toArray( new Integer[ isolated.size() ] ) ); 91 | // } 92 | return v; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/dbmodel/DBReference.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.dbmodel; 2 | 3 | import java.util.List; 4 | 5 | import pt.evolute.utils.object.DefaultLightPropertyObject; 6 | import pt.evolute.utils.tables.ColumnizedObject; 7 | 8 | /** 9 | * 10 | * @author lflores 11 | */ 12 | public class DBReference extends DefaultLightPropertyObject 13 | implements ColumnizedObject, Cloneable 14 | { 15 | public static final String NAME = "NAME"; 16 | public static final String SRC_COLUMNS = "SRC_COLUMNS"; 17 | public static final String SRC_TABLE = "SRC_TABLE"; 18 | public static final String DEST_COLUMNS = "DEST_COLUMNS"; 19 | public static final String DEST_TABLE = "DEST_TABLE"; 20 | 21 | private final ModelProvider provider; 22 | 23 | // private DBTable destTable = null; 24 | 25 | /** Creates a new instance of DBReference */ 26 | public DBReference( ModelProvider provider ) 27 | { 28 | super( new String[] { NAME, SRC_COLUMNS, SRC_TABLE, DEST_COLUMNS, DEST_TABLE }, false ); 29 | this.provider = provider; 30 | } 31 | 32 | public String getXMLRepresentation() 33 | { 34 | return null; 35 | } 36 | 37 | public void setXMLRepresentation() 38 | { 39 | } 40 | 41 | @SuppressWarnings("unchecked") 42 | public Object getValue( int col ) 43 | { 44 | return get( getPropertyNames()[ col ] ); 45 | } 46 | 47 | public DBTable getDestinationTable() 48 | { 49 | return ( DBTable ) get( DEST_TABLE ); 50 | } 51 | 52 | @Override 53 | public Object clone() 54 | { 55 | DBReference reference = new DBReference( provider ); 56 | reference.setMapData( getMapData() ); 57 | return reference; 58 | } 59 | 60 | @SuppressWarnings("unchecked") 61 | @Override 62 | public String toString() 63 | { 64 | StringBuffer buff = new StringBuffer(); 65 | String srcTable = "" + get( SRC_TABLE ); 66 | String destTable = "" + get( DEST_TABLE ); 67 | List srcColumns = ( List )get( SRC_COLUMNS ); 68 | List destColumns = ( List )get( DEST_COLUMNS ); 69 | for( int n = 0; n < srcColumns.size(); n++ ) 70 | { 71 | buff.append( "[" + srcTable + "." + srcColumns.get( n ).get( DBColumn.NAME ) + " -> " ); 72 | buff.append( destTable + "." + destColumns.get( n ).get( DBColumn.NAME ) + "]" ); 73 | } 74 | return buff.toString(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/backend/PostgreSQLBackend.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.backend; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.sql.SQLFeatureNotSupportedException; 7 | import java.sql.Statement; 8 | 9 | import pt.evolute.utils.error.ErrorLogger; 10 | import pt.evolute.utils.sql.function.SQLConcat; 11 | import pt.evolute.utils.sql.function.SQLFunction; 12 | import pt.evolute.utils.string.EvoStringUtils; 13 | import pt.evolute.utils.string.UnicodeChecker; 14 | 15 | public class PostgreSQLBackend extends DefaultBackend 16 | { 17 | private boolean useDoubleSlash = true; 18 | 19 | private boolean jdbc4method = true; 20 | 21 | public PostgreSQLBackend() 22 | { 23 | registerReservedKeyword( "user" ); 24 | registerReservedKeyword( "order" ); 25 | registerReservedKeyword( "table" ); 26 | } 27 | 28 | @Override 29 | public void config( Connection con ) 30 | { 31 | try 32 | { 33 | Statement stm = con.createStatement(); 34 | stm.execute( "SELECT '\\\\'" ); 35 | ResultSet rs = stm.getResultSet(); 36 | if( rs.next() ) 37 | { 38 | if( rs.getString( 1 ).length() == "\\\\".length() ) 39 | { 40 | useDoubleSlash = false; 41 | } 42 | } 43 | stm.close(); 44 | } 45 | catch( SQLException ex ) 46 | { 47 | ErrorLogger.logException( ex ); 48 | } 49 | } 50 | 51 | @Override 52 | public CharSequence escapeUnicode( CharSequence str ) 53 | { 54 | return getEscapeUnicode() ? UnicodeChecker.parseToUnicode( str, true, useDoubleSlash ) : EvoStringUtils.parsePlica( str ); 55 | } 56 | 57 | @Override 58 | public boolean isValid(Connection con) 59 | throws SQLException 60 | { 61 | boolean valid = false; 62 | if( jdbc4method ) 63 | { 64 | try 65 | { 66 | valid = super.isValid( con ); 67 | } 68 | catch( SQLFeatureNotSupportedException ex ) 69 | { 70 | jdbc4method = false; 71 | } 72 | } 73 | if( !jdbc4method ) 74 | { 75 | Statement stm = con.createStatement(); 76 | stm.execute( "SELECT 1" ); 77 | stm.close(); 78 | valid = true; 79 | } 80 | return valid; 81 | } 82 | 83 | @Override 84 | public CharSequence getUserFunctionName( SQLFunction fun ) 85 | { 86 | String name = fun.getName(); 87 | if( fun instanceof SQLConcat ) 88 | { 89 | name = "||"; 90 | } 91 | return name; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/PrimaryKeyMetadataConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * PrimaryKeyMetadataConstants.java 3 | * 4 | * Created on 5 de Dezembro de 2006, 18:28 5 | * 6 | * To change this template, choose Tools | Template Manager 7 | * and open the template in the editor. 8 | */ 9 | 10 | package pt.evolute.utils.db; 11 | 12 | /** 13 | * 14 | * @author fpalma 15 | */ 16 | public interface PrimaryKeyMetadataConstants 17 | { 18 | public static final String TABLE_CAT = "TABLE_CAT"; 19 | public static final String TABLE_SCHEM = "TABLE_SCHEM"; 20 | public static final String TABLE_NAME = "TABLE_NAME"; 21 | public static final String COLUMN_NAME = "COLUMN_NAME"; 22 | public static final String KEY_SEQ = "KEY_SEQ"; 23 | public static final String PK_NAME = "PK_NAME"; 24 | 25 | public static final int INDEX_TABLE_CAT = 1; 26 | public static final int INDEX_TABLE_SCHEM = 2; 27 | public static final int INDEX_TABLE_NAME = 3; 28 | public static final int INDEX_COLUMN_NAME = 4; 29 | public static final int INDEX_KEY_SEQ = 5; 30 | public static final int INDEX_PK_NAME = 6; 31 | 32 | public static final String DESCRIPTIONS[] = 33 | new String[]{ "", 34 | TABLE_CAT, 35 | TABLE_SCHEM, 36 | TABLE_NAME, 37 | COLUMN_NAME, 38 | KEY_SEQ, 39 | PK_NAME 40 | }; 41 | 42 | public static final String TYPES[] = 43 | new String[]{ "", 44 | "String", 45 | "String", 46 | "String", 47 | "String", 48 | "short", 49 | "String" 50 | }; 51 | 52 | public static final boolean IS_USED[] = 53 | new boolean[]{ false, 54 | true, 55 | true, 56 | true, 57 | true, 58 | true, 59 | true 60 | }; 61 | 62 | public static final boolean IS_CLASS[] = 63 | new boolean[]{ false, 64 | true, 65 | true, 66 | true, 67 | true, 68 | false, 69 | true 70 | }; 71 | 72 | public static final Class CLASS_FOR_TYPE[] = 73 | new Class[]{ null, 74 | String.class, 75 | String.class, 76 | String.class, 77 | String.class, 78 | Short.class, 79 | String.class 80 | }; 81 | 82 | public static final String COMMENTS[] = 83 | new String[]{ "", 84 | "table catalog (may be null)", 85 | "table schema (may be null)", 86 | "table name", 87 | "column name", 88 | "sequence number within primary key", 89 | "primary key name (may be null)" 90 | }; 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/Assignment.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql; 2 | 3 | import pt.evolute.utils.sql.backend.Backend; 4 | import pt.evolute.utils.sql.backend.BackendProvider; 5 | 6 | public class Assignment 7 | { 8 | private final Operand iValue; 9 | private final Field iField; 10 | 11 | private Backend backend = null; 12 | 13 | public Assignment( String field, Object value ) 14 | { 15 | this( new Field( field ), new Operand( value ) ); 16 | } 17 | 18 | public Assignment( Field field, Object value ) 19 | { 20 | this( field, new Operand( value ) ); 21 | } 22 | 23 | private Assignment( Field field, Operand value ) 24 | { 25 | iValue = value; 26 | iField = field; 27 | } 28 | 29 | @Override 30 | public String toString() 31 | { 32 | if( iValue != null ) 33 | { 34 | iValue.setBackend( getBackend() ); 35 | } 36 | if( iField == null ) 37 | { 38 | return null; 39 | } 40 | String value = ""; 41 | if( iValue.getInnerObject() instanceof byte[] ) 42 | { 43 | value = "?"; 44 | } 45 | else 46 | { 47 | value = iValue.toString(); 48 | } 49 | return iField.toString() + " = " + value; 50 | } 51 | 52 | public String getLeft() 53 | { 54 | return iField.toString(); 55 | } 56 | 57 | public String getRight() 58 | { 59 | String value = ""; 60 | if( iValue.getInnerObject() instanceof byte[] ) 61 | { 62 | value = "?"; 63 | } 64 | else 65 | { 66 | value = iValue.toString(); 67 | } 68 | return value; 69 | } 70 | 71 | public boolean isBatch() 72 | { 73 | return iValue.isBatch(); 74 | } 75 | 76 | public int getBatchSize() 77 | { 78 | return iValue.getBatchSize(); 79 | } 80 | 81 | public void currentBatch( int index ) 82 | { 83 | iValue.currentBatch( index ); 84 | } 85 | 86 | protected Operand getOperand() 87 | { 88 | return iValue; 89 | } 90 | 91 | public void setBackend( Backend backend ) 92 | { 93 | this.backend = backend; 94 | if( iValue != null ) 95 | { 96 | iValue.setBackend( backend ); 97 | } 98 | if( iField != null ) 99 | { 100 | iField.setBackend( backend ); 101 | } 102 | } 103 | 104 | protected Backend getBackend() 105 | { 106 | if( backend == null ) 107 | { 108 | // new Exception( "NO BACKEND!!!!" ).printStackTrace( System.out ); 109 | setBackend( BackendProvider.getDefaultBackend() ); 110 | } 111 | return backend; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/arrays/LightResultSet2DArray.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.arrays; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.SQLException; 5 | 6 | import pt.evolute.utils.error.ErrorLogger; 7 | 8 | public class LightResultSet2DArray implements Virtual2DArray 9 | { 10 | private final ResultSet results; 11 | 12 | private final int columns; 13 | private final Object currentRowData[]; 14 | 15 | private int rows = -1; 16 | 17 | private int currentRow = -1; 18 | 19 | 20 | public LightResultSet2DArray( ResultSet rs ) 21 | throws SQLException 22 | { 23 | results = rs; 24 | columns = results.getMetaData().getColumnCount(); 25 | currentRowData = new Object[ columns ]; 26 | } 27 | 28 | @SuppressWarnings("unchecked") 29 | @Override 30 | public RETURN_TYPE get(int row, int col) 31 | { 32 | RETURN_TYPE obj = null; 33 | if( row == currentRow ) 34 | { 35 | obj = (RETURN_TYPE)currentRowData[ col ]; 36 | } 37 | else 38 | { 39 | currentRow = row; 40 | try 41 | { 42 | results.absolute( row + 1 ); 43 | for( int i = 0; i < columns; ++i ) 44 | { 45 | currentRowData[ i ] = results.getObject( i + 1 ); 46 | } 47 | obj = (RETURN_TYPE)currentRowData[ col ]; 48 | if( row + 1 == rows ) 49 | { 50 | System.out.println( "\nClosing ResultSet (" + row + ")" ); 51 | results.getStatement().close(); 52 | } 53 | } 54 | catch( SQLException ex ) 55 | { 56 | ex.printStackTrace( System.out ); 57 | ErrorLogger.logException( ex ); 58 | } 59 | } 60 | return obj; 61 | } 62 | 63 | @Override 64 | public int columnCount() 65 | { 66 | return columns; 67 | } 68 | 69 | @Override 70 | public int rowCount() 71 | { 72 | if( rows == -1 ) 73 | { 74 | try 75 | { 76 | results.last(); 77 | rows = results.getRow(); 78 | } 79 | catch( SQLException ex ) 80 | { 81 | ErrorLogger.logException( ex ); 82 | } 83 | } 84 | return rows; 85 | } 86 | 87 | 88 | @Override 89 | public Object[][] getObjects() 90 | { 91 | int cols = columnCount(); 92 | int rows = rowCount(); 93 | Object o[][] = new Object[ rows ][]; 94 | for( int i = 0; i < rows; ++i ) 95 | { 96 | o[ i ] = new Object[ cols ]; 97 | for( int j = 0; j < cols; ++j ) 98 | { 99 | o[ i ][ j ] = get( i, j ); 100 | } 101 | } 102 | return o; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/Singleton.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import pt.evolute.utils.error.ErrorLogger; 7 | 8 | public class Singleton 9 | { 10 | public static final String USERNAME = "USERNAME"; 11 | public static final String USER_ID = "USER_ID"; 12 | public static final String USERNAME_FULL = "USERNAME_FULL"; 13 | public static final String PASSWORD = "PASSWORD"; 14 | public static final String TRACKER = "TRACKER"; 15 | public static final String DEFAULT_DBMANAGER = "DEFAULT_DBMANAGER"; 16 | public static final String DEFAULT_PERSISTENCE_MANAGER_FACTORY = "DEFAULT_PERSISTENCE_MANAGER_FACTORY"; 17 | public static final String DEFAULT_JDO_PROVIDER = "DEFAULT_JDO_PROVIDER"; 18 | public static final String DEFAULT_OBJECT_PROVIDER = "DEFAULT_OBJECT_PROVIDER"; 19 | public static final String DEFAULT_EVO_DATA_PROVIDER = "DEFAULT_EVO_DATA_PROVIDER"; 20 | public static final String TODAY = "TODAY"; 21 | public static final String DEFAULT_DATABASE_TYPE = "DEFAULT_DATABASE_TYPE"; 22 | public static final String PROPERTIES = "PROPERTIES"; 23 | public static final String PROPERTIES_PATH = "PROPERTIES_PATH"; 24 | public static final String DATABASE_NAME = "db.name"; 25 | 26 | 27 | /* End of names */ 28 | private static final Map hash = new HashMap(); 29 | private static final Map locked = new HashMap(); 30 | 31 | public static Object setInstance( String name, Object obj ) 32 | { 33 | if( Boolean.TRUE.equals( locked.get( name ) ) ) 34 | { 35 | ErrorLogger.logException( new Exception( "Tried to change locked property: " + name + "(old: " + getInstance( name ) + " new: " + obj + ")" ) ); 36 | throw new RuntimeException( "Tried to change locked property: " + name + "(old: " + getInstance( name ) + " new: " + obj + ")" ); 37 | } 38 | else 39 | { 40 | if( obj == null ) 41 | { 42 | obj = getInstance( name ); 43 | hash.remove( name ); 44 | return obj; 45 | } 46 | else 47 | { 48 | return hash.put( name, obj ); 49 | } 50 | } 51 | } 52 | 53 | public static Object getInstance( String name ) 54 | { 55 | return hash.get( name ); 56 | } 57 | 58 | public static void clear() 59 | { 60 | hash.clear(); 61 | } 62 | 63 | public static void lock( String name ) 64 | { 65 | locked.put( name, Boolean.TRUE ); 66 | } 67 | 68 | public static void unlock( String name ) 69 | { 70 | locked.put( name, Boolean.FALSE ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/table/JoinExpression.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.table; 2 | 3 | import pt.evolute.utils.Singleton; 4 | import pt.evolute.utils.db.DBConstants; 5 | import pt.evolute.utils.sql.Expression; 6 | 7 | /** 8 | * 9 | * @author fpalma 10 | */ 11 | public class JoinExpression 12 | implements DBConstants, TableExpression 13 | { 14 | // public static final int LEFT_OUTER = 0; 15 | 16 | protected final String table; 17 | protected final String outer[][]; 18 | protected final JoinExpression joins[][]; 19 | protected final Expression conditions[]; 20 | 21 | protected String joinDatabaseType; 22 | protected JoinBuilder joinBuilder; 23 | 24 | /** Creates a new instance of JoinExpression */ 25 | public JoinExpression( String table, String outer, Expression joinCondition, 26 | String databaseType ) 27 | { 28 | this( table, new String[][]{ { outer } }, null, new Expression[]{ joinCondition }, databaseType ); 29 | } 30 | 31 | public JoinExpression( String table, String outer[], JoinExpression joins[], Expression joinCondition, 32 | String databaseType ) 33 | { 34 | this( table, new String[][]{ outer }, new JoinExpression[][]{ joins }, 35 | new Expression[]{ joinCondition }, databaseType ); 36 | } 37 | 38 | public JoinExpression( String table, String outer[][], JoinExpression joins[][], Expression joinConditions[], 39 | String databaseType ) 40 | { 41 | this.table = table; 42 | this.outer = outer; 43 | if( joins != null ) 44 | { 45 | this.joins = joins; 46 | } 47 | else 48 | { 49 | this.joins = new JoinExpression[ outer.length ][ 0 ]; 50 | } 51 | conditions = joinConditions; 52 | if( databaseType == null ) 53 | { 54 | joinDatabaseType = ( String ) Singleton.getInstance( Singleton.DEFAULT_DATABASE_TYPE ); 55 | } 56 | else 57 | { 58 | joinDatabaseType = databaseType; 59 | } 60 | } 61 | 62 | public void setDatabaseType( String type ) 63 | { 64 | joinDatabaseType = type; 65 | } 66 | 67 | @Override 68 | public String toString() 69 | { 70 | initBuilder(); 71 | return joinBuilder.getHeader(); 72 | } 73 | 74 | public String getHeader() 75 | { 76 | initBuilder(); 77 | return joinBuilder.getHeader(); 78 | } 79 | 80 | public Expression getWhereExpression() 81 | { 82 | initBuilder(); 83 | return joinBuilder.getFilter(); 84 | } 85 | 86 | private void initBuilder() 87 | { 88 | if( joinBuilder == null ) 89 | { 90 | joinBuilder = JoinBuilderFactory.getJoinBuilder( this ); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/table/DefaultTable.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.table; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import pt.evolute.utils.sql.Field; 7 | 8 | /** 9 | * 10 | * @author fpalma 11 | */ 12 | public class DefaultTable 13 | implements Table 14 | { 15 | protected final String NAME; 16 | protected final Map FIELDS_BY_NAME = new HashMap(); 17 | protected final String []FIELD_NAMES; 18 | protected final Field []FIELDS; 19 | protected final String ALIAS; 20 | protected boolean temp; 21 | 22 | public DefaultTable( String name ) 23 | { 24 | this( name, null ); 25 | } 26 | 27 | public DefaultTable( String name, String fieldNames[] ) 28 | { 29 | this( name, fieldNames, null ); 30 | } 31 | 32 | /** Creates a new instance of DefaultTable */ 33 | public DefaultTable( String name, String fieldNames[], String alias ) 34 | { 35 | NAME = name; 36 | if( fieldNames == null ) 37 | { 38 | FIELD_NAMES = new String[ 0 ]; 39 | FIELDS = new Field[ 0 ]; 40 | } 41 | else 42 | { 43 | FIELD_NAMES = fieldNames; 44 | FIELDS = new Field[ FIELD_NAMES.length ]; 45 | } 46 | for( int n = 0; n < FIELD_NAMES.length; n++ ) 47 | { 48 | Field field = new Field( FIELD_NAMES[ n ], this ); 49 | FIELDS_BY_NAME.put( FIELD_NAMES[ n ], field ); 50 | FIELDS[ n ] = field; 51 | } 52 | ALIAS = alias; 53 | temp = false; 54 | } 55 | 56 | public String[] getAllFieldNames() 57 | { 58 | return FIELD_NAMES; 59 | } 60 | 61 | 62 | 63 | public Field getField(String fieldName) 64 | { 65 | return FIELDS_BY_NAME.get( fieldName ); 66 | } 67 | 68 | public String getHeader() 69 | { 70 | if( ALIAS == null ) 71 | { 72 | return NAME; 73 | } 74 | else 75 | { 76 | return ALIAS; 77 | } 78 | } 79 | 80 | @Override 81 | public String toString() 82 | { 83 | if( ALIAS == null ) 84 | { 85 | return NAME; 86 | } 87 | else 88 | { 89 | return ALIAS; 90 | } 91 | } 92 | 93 | public String getAlias() 94 | { 95 | return ALIAS; 96 | } 97 | 98 | public String getName() 99 | { 100 | return NAME; 101 | } 102 | 103 | public void setTemp() 104 | { 105 | temp = true; 106 | } 107 | 108 | public boolean isTemp() 109 | { 110 | return temp; 111 | } 112 | 113 | public Field[] getAllFields() 114 | { 115 | return FIELDS; 116 | } 117 | 118 | public Field[] getFields(String[] names) 119 | { 120 | Field fields[] = new Field[ names.length ]; 121 | for( int n = 0; n < names.length; n++ ) 122 | { 123 | fields[ n ] = FIELDS_BY_NAME.get( names[ n ] ); 124 | } 125 | return fields; 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/Config.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer; 2 | 3 | import java.util.Properties; 4 | 5 | public class Config implements ConfigurationProperties{ 6 | private static Properties PROPS = new Properties(); 7 | 8 | public static boolean ignoreEmpty() 9 | { 10 | return getValue( ONLY_NOT_EMPTY ); 11 | } 12 | 13 | public static boolean analyse() 14 | { 15 | return getValue( ANALYSE ); 16 | } 17 | 18 | private static boolean getValue( String name ) { 19 | return Boolean.parseBoolean( PROPS.getProperty( name, "false" ) ); 20 | } 21 | 22 | public static void setProperties(Properties p) { 23 | PROPS.putAll( p ); 24 | } 25 | 26 | public static boolean debug() { 27 | return getValue( DEBUG ); 28 | } 29 | 30 | public static boolean transfer() { 31 | return getValue( TRANSFER ); 32 | } 33 | 34 | public static boolean constrain() { 35 | return getValue( CONSTRAIN ); 36 | } 37 | 38 | public static boolean diff() { 39 | return getValue( DIFF ); 40 | } 41 | 42 | public static int getParallelThreads() 43 | { 44 | int t = 1; 45 | String s = PROPS.getProperty( TRANSFER_THREADS ); 46 | if( s != null && !s.isEmpty() ) 47 | { 48 | try 49 | { 50 | t = Integer.parseInt( s ); 51 | } 52 | catch( NumberFormatException ex ) 53 | { 54 | System.err.println( "Error in property: " + TRANSFER_THREADS + "=" + s ); 55 | } 56 | } 57 | return t; 58 | } 59 | 60 | public static boolean checkDependencies() { 61 | return getValue( TRANSFER_CHECK_DEPS ); 62 | } 63 | 64 | public static String getDiffComment() { 65 | return PROPS.getProperty( DIFF_COMMENT ); 66 | } 67 | 68 | public static boolean escapeUnicode() { 69 | return getValue( TRANSFER_ESCAPE_UNICODE ); 70 | } 71 | 72 | public static String getDestinationTablePrefix() 73 | { 74 | return PROPS.getProperty( DESTINATION_TABLE_PREFIX, "" ); 75 | } 76 | 77 | public static String getAnalyseDeleteIfExists() 78 | { 79 | return PROPS.getProperty( ANALYSE_DELETE_IF_EXISTS, "false" ); 80 | } 81 | 82 | public static String getDiffIgnoreDestinationTableCount() 83 | { 84 | return PROPS.getProperty( DIFF_IGNORE_DESTINATION_TABLE_COUNT, "false" ); 85 | } 86 | 87 | public static String getDiffIgnoreTablesWithoutPrimaryKey() 88 | { 89 | return PROPS.getProperty( DIFF_IGNORE_TABLES_WITHOUT_PRIMARY_KEY, "false" ); 90 | } 91 | 92 | public static String getDiffPrimaryKeyAllColumnsIfMissing() 93 | { 94 | return PROPS.getProperty( DIFF_PRIMARY_KEY_ALL_COLUMNS_IF_MISSING, "true" ); 95 | } 96 | 97 | public static String getDiffUseMD5() 98 | { 99 | return PROPS.getProperty( DIFF_USE_MD5, "true" ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/ConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Constants.java 3 | * 4 | * Created on February 7, 2005, 12:01 AM 5 | */ 6 | 7 | package pt.evolute.dbtransfer; 8 | 9 | /** 10 | * 11 | * @author lflores 12 | */ 13 | public interface ConfigurationProperties 14 | { 15 | public final static String URL_DB_SOURCE = "URL_DB_SOURCE"; 16 | public final static String USER_DB_SOURCE = "USER_DB_SOURCE"; 17 | public final static String PASSWORD_DB_SOURCE = "PASSWORD_DB_SOURCE"; 18 | public final static String SCHEMA_DB_SOURCE = "SCHEMA_DB_SOURCE"; 19 | 20 | public final static String[] SOURCE_PROPS = { URL_DB_SOURCE, USER_DB_SOURCE, PASSWORD_DB_SOURCE, SCHEMA_DB_SOURCE }; 21 | 22 | public final static String URL_DB_DESTINATION = "URL_DB_DESTINATION"; 23 | public final static String USER_DB_DESTINATION = "USER_DB_DESTINATION"; 24 | public final static String PASSWORD_DB_DESTINATION = "PASSWORD_DB_DESTINATION"; 25 | public final static String SCHEMA_DB_DESTINATION = "SCHEMA_DB_DESTINATION"; 26 | public final static String DESTINATION_TABLE_PREFIX = "DESTINATION_TABLE_PREFIX"; 27 | 28 | public final static String DESTINATION_PROPS[] = { URL_DB_DESTINATION, USER_DB_DESTINATION, PASSWORD_DB_DESTINATION, SCHEMA_DB_DESTINATION, DESTINATION_TABLE_PREFIX }; 29 | 30 | public final static String ANALYSE = "ANALYSE"; 31 | public final static String ANALYSE_DELETE_IF_EXISTS = "ANALYSE_DELETE_IF_EXISTS"; 32 | 33 | public final static String ONLY_NOT_EMPTY = "ONLY_NOT_EMPTY"; 34 | 35 | public final static String TRANSFER = "TRANSFER"; 36 | public final static String TRANSFER_THREADS = "TRANSFER.THREADS"; 37 | public final static String TRANSFER_ESCAPE_UNICODE = "TRANSFER.ESCAPE_UNICODE"; 38 | public final static String TRANSFER_CHECK_DEPS = "TRANSFER.CHECK_DEPS"; 39 | public final static String TRANSFER_USE_DEST_FOR_DEPS = "TRANSFER.USE_DEST_FOR_DEPS"; 40 | public final static String TRANSFER_MAX_READ_ROWS = "TRANSFER.MAX_READ_ROWS"; 41 | public final static String TRANSFER_IGNORE_BLOBS = "TRANSFER.IGNORE_BLOBS"; 42 | 43 | public final static String CONSTRAIN = "CONSTRAIN"; 44 | 45 | public final static String DIFF = "DIFF"; 46 | public final static String DIFF_COMMENT = "DIFF.COMMENT"; 47 | public final static String DIFF_USE_MD5 = "DIFF.USE_MD5"; 48 | public final static String DIFF_IGNORE_DESTINATION_TABLE_COUNT = "DIFF.IGNORE_DESTINATION_TABLE_COUNT"; 49 | public final static String DIFF_IGNORE_TABLES_WITHOUT_PRIMARY_KEY = "DIFF.IGNORE_TABLES_WITHOUT_PRIMARY_KEY"; 50 | public final static String DIFF_PRIMARY_KEY_ALL_COLUMNS_IF_MISSING = "DIFF.PRIMARY_KEY_ALL_COLUMNS_IF_MISSING"; 51 | 52 | public final static String DEBUG = "DEBUG"; 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/jackcess/Jackcess2DArray.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.jackcess; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.healthmarketscience.jackcess.Column; 7 | import com.healthmarketscience.jackcess.Table; 8 | 9 | import pt.evolute.utils.arrays.Virtual2DArray; 10 | import pt.evolute.utils.arrays.exception.EndOfArrayException; 11 | 12 | /** 13 | * 14 | * @author lflores 15 | */ 16 | public class Jackcess2DArray implements Virtual2DArray 17 | { 18 | private final Table table; 19 | // private final List columns; 20 | private final String columnNames[]; 21 | private int currentRow = -1; 22 | private Map currentRowMap; 23 | 24 | 25 | public Jackcess2DArray( Table t ) 26 | { 27 | table = t; 28 | List columns = table.getColumns(); 29 | columnNames = new String[ columns.size() ]; 30 | for( int i = 0; i < columns.size(); ++i ) 31 | { 32 | columnNames[ i ] = columns.get( i ).getName(); 33 | } 34 | } 35 | 36 | @SuppressWarnings("unchecked") 37 | @Override 38 | public RETURN_TYPE get(int r, int c) 39 | { 40 | Object o = null; 41 | if( r == currentRow + 1 ) 42 | { 43 | currentRow = r; 44 | try 45 | { 46 | currentRowMap = table.getNextRow(); 47 | } 48 | catch( Exception ex ) 49 | { 50 | ex.printStackTrace(); 51 | } 52 | if( currentRowMap == null && r == table.getRowCount() ) 53 | { 54 | throw new EndOfArrayException(); 55 | // System.out.println( "CurrentRowMap is null!!!! r=" + r + " total=" + table.getRowCount() ); 56 | } 57 | } 58 | if( r == currentRow ) 59 | { 60 | o = currentRowMap.get( columnNames[ c ] ); 61 | } 62 | else 63 | { 64 | System.out.println( "Invalid ROW: current: " + currentRow + " requested: " + r ); 65 | } 66 | return ( RETURN_TYPE )o; 67 | } 68 | 69 | public void set(int i, int i1, Object o) 70 | { 71 | throw new UnsupportedOperationException("Not supported yet."); 72 | } 73 | 74 | public int rowLength() 75 | { 76 | return columnCount(); 77 | } 78 | 79 | public int columnCount() 80 | { 81 | return table.getColumnCount(); 82 | } 83 | 84 | public int columnLength() 85 | { 86 | return rowCount(); 87 | } 88 | 89 | public int rowCount() 90 | { 91 | return table.getRowCount(); 92 | } 93 | 94 | public Object[][] getObjects() 95 | { 96 | throw new UnsupportedOperationException("Not supported yet."); 97 | } 98 | 99 | public void deleteRow(int i) 100 | { 101 | throw new UnsupportedOperationException("Not supported yet."); 102 | } 103 | 104 | public void appendEmptyRow() 105 | { 106 | throw new UnsupportedOperationException("Not supported yet."); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/table/PostgreSQLJoinBuilder.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.table; 2 | 3 | import pt.evolute.utils.db.DBConstants; 4 | import pt.evolute.utils.sql.Expression; 5 | /** 6 | * 7 | * @author fpalma 8 | */ 9 | public class PostgreSQLJoinBuilder 10 | implements JoinBuilder, DBConstants 11 | { 12 | protected String table; 13 | protected String outer[][]; 14 | protected JoinExpression joins[][]; 15 | protected JoinBuilder builders[][]; 16 | protected Expression joinConditions[]; 17 | 18 | protected Expression whereExpression = null; 19 | protected String header = null; 20 | 21 | /** Creates a new instance of PostgreSQLJoinBuilder */ 22 | public PostgreSQLJoinBuilder( String table, String outer[][], JoinExpression joins[][], 23 | Expression joinConditions[] ) 24 | { 25 | this.table = table; 26 | this.outer = outer; 27 | this.joins = joins; 28 | this.joinConditions = joinConditions; 29 | 30 | builders = new JoinBuilder[ joins.length ][]; 31 | for( int i = 0; i < builders.length; i++ ) 32 | { 33 | if( joins[ i ] != null ) 34 | { 35 | builders[ i ] = new JoinBuilder[ joins[ i ].length ]; 36 | } 37 | else 38 | { 39 | builders[ i ] = new JoinBuilder[ 0 ]; 40 | } 41 | for( int j = 0; j < builders[ i ].length; j++ ) 42 | { 43 | builders[ i ][ j ] = JoinBuilderFactory.getJoinBuilder( joins[ i ][ j ] ); 44 | } 45 | } 46 | } 47 | 48 | public String getDatabaseType() 49 | { 50 | return DB_POSTGRESQL; 51 | } 52 | 53 | public Expression getFilter() 54 | { 55 | return null; 56 | } 57 | 58 | public String getHeader() 59 | { 60 | if( header == null ) 61 | { 62 | header = table; 63 | for( int i = 0; i < outer.length; i++ ) 64 | { 65 | header += " LEFT OUTER JOIN "; 66 | if( ( outer[ i ] != null && outer[ i ].length > 1 ) 67 | || builders[ i ].length > 0 ) 68 | { 69 | header += "( "; 70 | } 71 | if( outer[ i ] != null && outer[ i ].length > 0 ) 72 | { 73 | header += outer[ i ][ 0 ]; 74 | for( int j = 1; j < outer[ i ].length; j++ ) 75 | { 76 | header += ", " + outer[ i ][ j ]; 77 | } 78 | } 79 | if( builders[ i ].length > 0 ) 80 | { 81 | if( outer[ i ] != null && outer[ i ].length > 0 ) 82 | { 83 | header += ", "; 84 | } 85 | header += builders[ i ][ 0 ].getHeader(); 86 | for( int j = 1; j < builders[ i ].length; j++ ) 87 | { 88 | header += ", " + builders[ i ][ j ].getHeader(); 89 | } 90 | } 91 | if( ( outer[ i ] != null && outer[ i ].length > 1 ) 92 | || builders[ i ].length > 0 ) 93 | { 94 | header += " )"; 95 | } 96 | header += " ON ( " + joinConditions[ i ] + " )"; 97 | } 98 | } 99 | return header; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/PrimaryKeyValue.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db; 2 | 3 | import java.text.DateFormat; 4 | import java.text.SimpleDateFormat; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class PrimaryKeyValue 9 | { 10 | public final static DateFormat D_F = new SimpleDateFormat( "yyyy-MM-dd" ); 11 | public final static DateFormat T_F = new SimpleDateFormat( "HH:mm:ss" ); 12 | public final static DateFormat TS_F = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); 13 | 14 | private final List v = new ArrayList(); 15 | 16 | public void add( Object o ) 17 | { 18 | v.add( o ); 19 | } 20 | 21 | public Object get( int p ) 22 | { 23 | return v.get( p ); 24 | } 25 | 26 | public Object[] toArray() 27 | { 28 | return v.toArray(); 29 | } 30 | 31 | public List getList() 32 | { 33 | return new ArrayList( v ); 34 | } 35 | 36 | @Override 37 | public int hashCode() 38 | { 39 | // int i = 0; 40 | // int shift = 1; 41 | // for( Object o: v ) 42 | // { 43 | // if( o == null ) 44 | // { 45 | // o = "null"; 46 | // } 47 | // if( o instanceof java.sql.Date ) 48 | // { 49 | // o = D_F.format( o ); 50 | // } 51 | // else if( o instanceof java.sql.Time ) 52 | // { 53 | // o = T_F.format( o ); 54 | // } 55 | // else if( o instanceof java.sql.Timestamp ) 56 | // { 57 | // o = TS_F.format( o ); 58 | // } 59 | // ++shift; 60 | // i += o.hashCode() << shift; 61 | // } 62 | // return i; 63 | return toString().hashCode(); 64 | } 65 | 66 | @Override 67 | public boolean equals( Object o ) 68 | { 69 | boolean b = false; 70 | if( o != null && o instanceof PrimaryKeyValue ) 71 | { 72 | PrimaryKeyValue o1 = (PrimaryKeyValue)o; 73 | b = o1.toString().equals( toString() ); 74 | } 75 | return b; 76 | } 77 | 78 | @Override 79 | public String toString() 80 | { 81 | StringBuilder sb = new StringBuilder(); 82 | for( Object o: v ) 83 | { 84 | sb.append( "*" ); 85 | if( o instanceof java.sql.Date ) 86 | { 87 | sb.append( PrimaryKeyValue.D_F.format( o ) ); 88 | } 89 | else if( o instanceof java.sql.Time ) 90 | { 91 | sb.append( PrimaryKeyValue.T_F.format( o ) ); 92 | } 93 | else if( o instanceof java.sql.Timestamp ) 94 | { 95 | sb.append( PrimaryKeyValue.TS_F.format( o ) ); 96 | } 97 | else 98 | { 99 | sb.append( "" + o ); 100 | } 101 | } 102 | return sb.toString(); 103 | } 104 | 105 | public int compareTo(PrimaryKeyValue otherKey) { 106 | int c = 0; 107 | for( int i = 0; i < v.size(); ++i ) 108 | { 109 | String s = "" + v.get( i ); 110 | String s2 = "" + otherKey.v.get( i ); 111 | c = s.compareTo( s2 ); 112 | if( c != 0 ) 113 | { 114 | break; 115 | } 116 | } 117 | return c; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/object/DefaultLightPropertyObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DefaultLightPropertyObject.java 3 | * 4 | * Created on 30 de Novembro de 2006, 19:04 5 | * 6 | * To change this template, choose Tools | Template Manager 7 | * and open the template in the editor. 8 | */ 9 | 10 | package pt.evolute.utils.object; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Arrays; 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | 19 | /** 20 | * 21 | * @author fpalma 22 | */ 23 | public class DefaultLightPropertyObject 24 | implements LightPropertyObject 25 | { 26 | protected static final String NO_PROPERTIES[] = new String[ 0 ]; 27 | protected final String PROPERTIES[]; 28 | protected final List PROPERTY_LIST = new ArrayList(); 29 | protected final boolean ENFORCE_PROPERTY_LIST; 30 | 31 | protected final HashMap DATA = new HashMap(); 32 | 33 | /** Creates a new instance of DefaultLightPropertyObject */ 34 | public DefaultLightPropertyObject() 35 | { 36 | this( NO_PROPERTIES, false ); 37 | } 38 | 39 | public DefaultLightPropertyObject( String properties[], boolean enforcePropertyList ) 40 | { 41 | if( properties == null ) 42 | { 43 | PROPERTIES = NO_PROPERTIES; 44 | } 45 | else 46 | { 47 | PROPERTIES = properties; 48 | } 49 | ENFORCE_PROPERTY_LIST = enforcePropertyList; 50 | PROPERTY_LIST.addAll( Arrays.asList( PROPERTIES ) ); 51 | } 52 | 53 | public Object get(String property) 54 | { 55 | if( ENFORCE_PROPERTY_LIST && !PROPERTY_LIST.contains( property ) ) 56 | { 57 | throw new InvalidPropertyException( property, "Valid properties are: " + PROPERTY_LIST ); 58 | } 59 | else 60 | { 61 | return DATA.get( property ); 62 | } 63 | } 64 | 65 | public void set(String property, Object value) 66 | { 67 | if( ENFORCE_PROPERTY_LIST && !PROPERTY_LIST.contains( property ) ) 68 | { 69 | throw new InvalidPropertyException( property, "Valid properties are: " + PROPERTY_LIST ); 70 | } 71 | else 72 | { 73 | DATA.put( property, value ); 74 | } 75 | } 76 | 77 | @Override 78 | public void setMapData(Map map) 79 | { 80 | DATA.putAll( map ); 81 | } 82 | 83 | @SuppressWarnings("unchecked") 84 | public Map getMapData() 85 | { 86 | return (Map) DATA.clone(); 87 | } 88 | 89 | public String[] getPropertyNames() 90 | { 91 | return PROPERTIES; 92 | } 93 | 94 | @Override 95 | public boolean equals( Object other ) 96 | { 97 | if( !( other instanceof DefaultLightPropertyObject ) ) 98 | { 99 | return false; 100 | } 101 | DefaultLightPropertyObject propertyObject = 102 | ( DefaultLightPropertyObject ) other; 103 | return ( ENFORCE_PROPERTY_LIST == propertyObject.ENFORCE_PROPERTY_LIST ) && 104 | ( getMapData().equals( propertyObject.getMapData() ) ) && 105 | ( PROPERTY_LIST.equals( propertyObject.PROPERTY_LIST ) ) ; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/table/InformixJoinBuilder.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.table; 2 | 3 | import pt.evolute.utils.db.DBConstants; 4 | import pt.evolute.utils.sql.Expression; 5 | /** 6 | * 7 | * @author fpalma 8 | */ 9 | public class InformixJoinBuilder 10 | implements JoinBuilder, DBConstants 11 | { 12 | protected String table; 13 | protected String outer[][]; 14 | protected JoinExpression joins[][]; 15 | protected JoinBuilder builders[][]; 16 | protected Expression joinConditions[]; 17 | 18 | protected Expression whereExpression = null; 19 | protected String header = null; 20 | 21 | /** Creates a new instance of InformixJoinBuilder */ 22 | public InformixJoinBuilder( String table, String outer[][], JoinExpression joins[][], 23 | Expression joinConditions[] ) 24 | { 25 | this.table = table; 26 | this.outer = outer; 27 | this.joins = joins; 28 | this.joinConditions = joinConditions; 29 | 30 | builders = new JoinBuilder[ joins.length ][]; 31 | for( int i = 0; i < builders.length; i++ ) 32 | { 33 | if( joins[ i ] != null ) 34 | { 35 | builders[ i ] = new JoinBuilder[ joins[ i ].length ]; 36 | } 37 | else 38 | { 39 | builders[ i ] = new JoinBuilder[ 0 ]; 40 | } 41 | for( int j = 0; j < builders[ i ].length; j++ ) 42 | { 43 | builders[ i ][ j ] = JoinBuilderFactory.getJoinBuilder( joins[ i ][ j ] ); 44 | } 45 | } 46 | } 47 | 48 | public String getDatabaseType() 49 | { 50 | return DB_INFORMIX; 51 | } 52 | 53 | public Expression getFilter() 54 | { 55 | if( whereExpression == null ) 56 | { 57 | whereExpression = joinConditions[ 0 ]; 58 | for( int n = 1; n < joinConditions.length; n++ ) 59 | { 60 | whereExpression = whereExpression.and( joinConditions[ n ] ); 61 | } 62 | for( int i = 0; i < builders.length; i++ ) 63 | { 64 | for( int j = 0; j < builders[ i ].length; j++ ) 65 | { 66 | whereExpression = whereExpression.and( builders[ i ][ j ].getFilter() ); 67 | } 68 | } 69 | } 70 | return whereExpression; 71 | } 72 | 73 | public String getHeader() 74 | { 75 | if( header == null ) 76 | { 77 | header = table; 78 | for( int i = 0; i < outer.length; i++ ) 79 | { 80 | header += ", OUTER "; 81 | if( ( outer[ i ] != null && outer[ i ].length > 1 ) 82 | || builders[ i ].length > 0 ) 83 | { 84 | header += "( "; 85 | } 86 | if( outer[ i ] != null && outer[ i ].length > 0 ) 87 | { 88 | header += outer[ i ][ 0 ]; 89 | for( int j = 1; j < outer[ i ].length; j++ ) 90 | { 91 | header += ", " + outer[ i ][ j ]; 92 | } 93 | } 94 | if( builders[ i ].length > 0 ) 95 | { 96 | if( outer[ i ] != null && outer[ i ].length > 0 ) 97 | { 98 | header += ", "; 99 | } 100 | header += builders[ i ][ 0 ].getHeader(); 101 | for( int j = 1; j < builders[ i ].length; j++ ) 102 | { 103 | header += ", " + builders[ i ][ j ].getHeader(); 104 | } 105 | } 106 | if( ( outer[ i ] != null && outer[ i ].length > 1 ) 107 | || builders[ i ].length > 0 ) 108 | { 109 | header += " )"; 110 | } 111 | } 112 | } 113 | return header; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/backend/BackendProvider.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.backend; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import pt.evolute.utils.error.ErrorLogger; 9 | 10 | public class BackendProvider 11 | { 12 | private static final Class DEFAULT_BACKEND_CLASS = DefaultBackend.class; 13 | 14 | private static final Map> BACKEND_CLASS_BY_PROTOCOL = new HashMap>(); 15 | 16 | private static final Map,Boolean> BACKEND_ESCAPES_UNICODE_BY_CLASS = new HashMap, Boolean>(); 17 | 18 | static 19 | { 20 | BACKEND_CLASS_BY_PROTOCOL.put( "postgresql", PostgreSQLBackend.class ); 21 | BACKEND_CLASS_BY_PROTOCOL.put( "sqlserver", SQLServerBackend.class ); 22 | BACKEND_CLASS_BY_PROTOCOL.put( "hsqldb", HSQLDBBackend.class ); 23 | BACKEND_CLASS_BY_PROTOCOL.put( "ucanaccess", HSQLDBBackend.class ); 24 | } 25 | 26 | private static Map BACKEND_BY_URL = new HashMap(); 27 | private static Map,List> BACKENDS_BY_CLASS = new HashMap,List>(); 28 | 29 | public static Backend getBackend( String url ) 30 | { 31 | Backend backend = BACKEND_BY_URL.get( url ); 32 | if( backend == null ) 33 | { 34 | String protocol = url.split( ":" )[ 1 ]; 35 | Class backendClass = BACKEND_CLASS_BY_PROTOCOL.get( protocol ); 36 | if( backendClass == null ) 37 | { 38 | System.out.println( "Using default db backend for protocol / url: " + protocol + " / " + url ); 39 | backendClass = DEFAULT_BACKEND_CLASS; 40 | } 41 | try 42 | { 43 | backend = backendClass.newInstance(); 44 | if( BACKEND_ESCAPES_UNICODE_BY_CLASS.containsKey( backendClass ) ) 45 | { 46 | backend.setEscapeUnicode( BACKEND_ESCAPES_UNICODE_BY_CLASS.get( backendClass ) ); 47 | } 48 | BACKEND_BY_URL.put( url, backend ); 49 | if( !BACKENDS_BY_CLASS.containsKey(backendClass) ) 50 | { 51 | BACKENDS_BY_CLASS.put(backendClass, new ArrayList() ); 52 | } 53 | BACKENDS_BY_CLASS.get( backendClass ).add( backend ); 54 | } 55 | catch( IllegalAccessException ex ) 56 | { 57 | ErrorLogger.logException( ex ); 58 | } 59 | catch( InstantiationException ex ) 60 | { 61 | ErrorLogger.logException( ex ); 62 | } 63 | } 64 | return backend; 65 | } 66 | 67 | public static Backend getDefaultBackend() 68 | { 69 | Backend backend = null; 70 | try 71 | { 72 | backend = DEFAULT_BACKEND_CLASS.newInstance(); 73 | } 74 | catch( IllegalAccessException ex ) 75 | { 76 | ErrorLogger.logException( ex ); 77 | } 78 | catch( InstantiationException ex ) 79 | { 80 | ErrorLogger.logException( ex ); 81 | } 82 | return backend; 83 | } 84 | 85 | public static void setBackendEscapesUnicodeByClass( Class clazz, Boolean escapes ) 86 | { 87 | BACKEND_ESCAPES_UNICODE_BY_CLASS.put( clazz, escapes ); 88 | List backends = BACKENDS_BY_CLASS.get( clazz ); 89 | if( backends != null ) 90 | { 91 | for( Backend backend : backends ) 92 | { 93 | backend.setEscapeUnicode( escapes ); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/arrays/CursorResultSet2DArray.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.arrays; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.SQLException; 5 | import pt.evolute.utils.arrays.exception.EndOfArrayException; 6 | 7 | import pt.evolute.utils.error.ErrorLogger; 8 | 9 | public class CursorResultSet2DArray implements Virtual2DArray 10 | { 11 | private final ResultSet results; 12 | 13 | private final int columns; 14 | private final Object currentRowData[]; 15 | 16 | private int rows = -1; 17 | 18 | private int currentRow = -1; 19 | private boolean validRow; 20 | 21 | public CursorResultSet2DArray( ResultSet rs ) 22 | throws SQLException 23 | { 24 | results = rs; 25 | columns = results.getMetaData().getColumnCount(); 26 | currentRowData = new Object[ columns ]; 27 | validRow = results.next(); 28 | // results.last(); 29 | // rows = results.getRow(); 30 | // if( !results.first() ) 31 | // { 32 | // System.out.println( "First not supported" ); 33 | // } 34 | } 35 | 36 | @SuppressWarnings("unchecked") 37 | @Override 38 | public RETURN_TYPE get(int row, int col) 39 | { 40 | RETURN_TYPE obj = null; 41 | if( row == currentRow ) 42 | { 43 | obj = (RETURN_TYPE)currentRowData[ col ]; 44 | } 45 | else 46 | { 47 | if( currentRow + 1 == row ) 48 | { 49 | currentRow = row; 50 | 51 | try 52 | { 53 | if( validRow ) 54 | { 55 | for( int i = 0; i < columns; ++i ) 56 | { 57 | currentRowData[ i ] = results.getObject( i + 1 ); 58 | } 59 | obj = (RETURN_TYPE)currentRowData[ col ]; 60 | if( !results.next() ) 61 | { 62 | rows = currentRow; 63 | validRow = false; 64 | // System.out.println( "\nClosing ResultSet (" + row + ")" ); 65 | results.getStatement().close(); 66 | } 67 | } 68 | else 69 | { 70 | rows = currentRow; 71 | throw new EndOfArrayException(); 72 | } 73 | } 74 | catch( SQLException ex ) 75 | { 76 | ex.printStackTrace( System.out ); 77 | ErrorLogger.logException( ex ); 78 | } 79 | } 80 | else 81 | { 82 | throw new RuntimeException( "invalid index " + currentRow + " get: " + row ); 83 | } 84 | } 85 | return obj; 86 | } 87 | 88 | @Override 89 | public int columnCount() 90 | { 91 | return columns; 92 | } 93 | 94 | @Override 95 | public int rowCount() 96 | { 97 | 98 | if( rows == -1 ) 99 | { 100 | throw new RuntimeException( "not supported" ); 101 | } 102 | return rows; 103 | } 104 | 105 | 106 | @Override 107 | public Object[][] getObjects() 108 | { 109 | throw new RuntimeException( "Not implemented yet" ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/condition/In.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql.condition; 2 | 3 | import java.util.List; 4 | 5 | import pt.evolute.utils.arrays.EvoArrays; 6 | import pt.evolute.utils.arrays.IntArrayIntervalFinder; 7 | import pt.evolute.utils.sql.Condition; 8 | import pt.evolute.utils.sql.Operand; 9 | 10 | public class In extends Condition 11 | { 12 | private final static int OPTIMIZE_SIZE = 20; 13 | // private final static int BETWEEN_SIZE = 5; 14 | // private final static double GAP_PERCENT = 0.33; 15 | 16 | private final static String connector_string = "OR"; 17 | private final static String between_prefix_string = ""; 18 | private final static String in_string = "IN"; 19 | 20 | private String leftStr = null; 21 | protected String symbolStr = null; 22 | private String rightStr = null; 23 | private boolean many = false; 24 | 25 | public In( Operand left, Operand right ) 26 | { 27 | super( left, right ); 28 | checkMany( left, right, getConnector() ); 29 | } 30 | 31 | public String getConnector() 32 | { 33 | return connector_string; 34 | } 35 | 36 | public String getBetweenPrefix() 37 | { 38 | return between_prefix_string; 39 | } 40 | 41 | public String getInString() 42 | { 43 | return in_string; 44 | } 45 | 46 | private void checkMany( Operand left, Operand right, String expressionConnector ) 47 | { 48 | if( right.isBatch() ) 49 | { 50 | Object data[] = right.getInnerData(); 51 | 52 | if( data instanceof Integer[] ) 53 | { 54 | Integer ints[] = ( Integer[] )data; 55 | if( ints.length < OPTIMIZE_SIZE ) 56 | { 57 | return; 58 | } 59 | ints = EvoArrays.sortAndDistinct( ints ); 60 | 61 | List intervals = IntArrayIntervalFinder.findIntervals( ints ); 62 | 63 | if( intervals.size() <= 1 ) 64 | { 65 | return; 66 | } 67 | many = true; 68 | ints = intervals.get( intervals.size() - 1 ); 69 | intervals.remove( intervals.size() - 1 ); 70 | if( ints.length > 0 ) 71 | { 72 | Operand newRight = new Operand( ints ); 73 | newRight.setBackend( getBackend() ); 74 | rightStr = newRight.toString(); 75 | } 76 | else 77 | { 78 | symbolStr = getBetweenPrefix() + "BETWEEN"; 79 | ints = intervals.get( intervals.size() - 1 ); 80 | intervals.remove( intervals.size() - 1 ); 81 | Operand op = new Operand( ints[ 0 ] ); 82 | op.setBackend( getBackend() ); 83 | Operand op2 = new Operand( ints[ 1 ] ); 84 | op2.setBackend( getBackend() ); 85 | rightStr = op + " AND " + op2; 86 | } 87 | for( int n = 0; n < intervals.size(); n++ ) 88 | { 89 | Between bet = new Between( left, new Operand( intervals.get( n ) ) ); 90 | bet.setBackend( getBackend() ); 91 | rightStr += " " + expressionConnector + " (" + getBetweenPrefix() + bet.toString() + ")"; 92 | } 93 | rightStr += ")"; 94 | } 95 | } 96 | } 97 | 98 | @Override 99 | public String getSymbol() 100 | { 101 | if( symbolStr == null ) 102 | { 103 | return getInString(); 104 | } 105 | else 106 | { 107 | return symbolStr; 108 | } 109 | } 110 | 111 | @Override 112 | public String getLeft() 113 | { 114 | if( leftStr == null ) 115 | { 116 | leftStr = super.getLeft(); 117 | if( many ) 118 | { 119 | leftStr = "(" + leftStr; 120 | } 121 | } 122 | return leftStr; 123 | } 124 | 125 | @Override 126 | public String getRight() 127 | { 128 | if( rightStr == null ) 129 | { 130 | rightStr = super.getRight(); 131 | } 132 | return rightStr; 133 | } 134 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/transfer/ReportThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | package pt.evolute.dbtransfer.transfer; 8 | 9 | import java.text.DecimalFormat; 10 | import java.text.NumberFormat; 11 | import java.util.List; 12 | 13 | /** 14 | * 15 | * @author lflores 16 | */ 17 | public class ReportThread extends Thread 18 | { 19 | private static final int SLEEP_TIME_MS = 5000; 20 | private static final NumberFormat NF = new DecimalFormat("##0.00E0"); 21 | 22 | private final Mover mover; 23 | private final List threads; 24 | 25 | private boolean running = true; 26 | 27 | private long lastReport = System.currentTimeMillis(); 28 | 29 | public ReportThread( Mover mov, List list ) 30 | { 31 | mover = mov; 32 | threads = list; 33 | setDaemon( true ); 34 | } 35 | 36 | private static final String suffix[] = { "", "k", "m", "g", "t", "e" }; 37 | 38 | private static String format( long l ) 39 | { 40 | String str = NF.format( l ); 41 | int i = str.indexOf( "E" ); 42 | int e = 0; 43 | if( i > -1 ) 44 | { 45 | e = Integer.parseInt( str.substring( i + 1 ) ) / 3; 46 | } 47 | str = str.substring( 0, i - 2 ); 48 | 49 | return str + suffix[ e ]; 50 | } 51 | 52 | @Override 53 | public void run() 54 | { 55 | int lastRead = 0; 56 | while( running || !threads.isEmpty() ) 57 | { 58 | System.out.println(); 59 | if( !running ) 60 | { 61 | System.out.println( "WAITING WRITES" ); 62 | } 63 | int r = mover.getReadCount(); 64 | long last = System.currentTimeMillis(); 65 | System.out.println( "READ: " + format( r - lastRead ) 66 | + " in " + ( last - lastReport ) + "ms" + ( mover.isSleeping()? " sleeping!":"" ) ); 67 | lastRead = r; 68 | if( threads.size() > 1 ) 69 | { 70 | System.out.println( "WRITING THREADS: " + threads.size() ); 71 | } 72 | for( AsyncStatement as: threads ) 73 | { 74 | int writeRows = as.getAndResetWriteRows(); 75 | int privateRows = as.getPrivateRowsSize(); 76 | int sharedRows = as.getSharedRowsSize(); 77 | last = System.currentTimeMillis(); 78 | System.out.println( "WRITE: " + as.getName() + " rows: " 79 | + format( writeRows ) + " in " + ( last - lastReport ) + "ms " 80 | + ( as.isSleeping()? "sleeping!": "" ) 81 | + " shared rows: " + sharedRows 82 | + " private rows: " + privateRows ); 83 | long totalMem = Runtime.getRuntime().totalMemory(); 84 | long freeMem = Runtime.getRuntime().freeMemory(); 85 | System.out.println( "free/allocated JVM memory: " + freeMem / (1024*1024) 86 | + "/" + totalMem / (1024*1024) + "MB" ); 87 | lastReport = last; 88 | // System.gc(); 89 | } 90 | try 91 | { 92 | sleep( SLEEP_TIME_MS ); 93 | } 94 | catch( InterruptedException ex ) 95 | { 96 | } 97 | } 98 | } 99 | 100 | public void stopReporting() 101 | { 102 | running = false; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/arrays/VectorArray.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.arrays; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class VectorArray 7 | { 8 | /* public static Vector arrayToVector( Object obj[] ) 9 | { 10 | return new Vector( Arrays.asList( obj ) ); 11 | } 12 | */ 13 | public static List arrayToStringVector( Object obj[] ) 14 | { 15 | List v = new ArrayList( obj.length ); 16 | for( int i = 0; i < obj.length; i++ ) 17 | { 18 | v.add( obj[i].toString() ); 19 | } 20 | 21 | return v; 22 | } 23 | 24 | public static int []mergeArrays( int array[][] ) 25 | { 26 | int total = 0; 27 | for( int i = 0; i < array.length; i++ ) 28 | { 29 | total += array[i].length; 30 | } 31 | 32 | int a[] = new int[total]; 33 | int current = 0; 34 | for( int i = 0; i < array.length; i++ ) 35 | { 36 | for( int j = 0; j < array[i].length; j++ ) 37 | { 38 | a[current++] = array[i][j]; 39 | } 40 | } 41 | 42 | return a; 43 | } 44 | 45 | public static int []integerToIntArray( Object array[] ) 46 | { 47 | int a[] = new int[array.length]; 48 | for( int i = 0; i < a.length; i++ ) 49 | { 50 | a[i] = (( Integer )array[i]).intValue(); 51 | } 52 | 53 | return a; 54 | } 55 | 56 | public static String intArrayToList( int array[] ) 57 | { 58 | if( array.length == 0 ) 59 | { 60 | return ""; 61 | } 62 | 63 | StringBuilder list = new StringBuilder(); 64 | list.append( array[0] ); 65 | 66 | for( int i = 1; i < array.length; i++ ) 67 | { 68 | list.append( ", " ); 69 | list.append( array[i] ); 70 | } 71 | 72 | return list.toString(); 73 | } 74 | 75 | public static String objectArrayToList( Object array[] ) 76 | { 77 | return objectArrayToList( array, false ); 78 | } 79 | 80 | public static String objectArrayToList( Object array[], boolean compact ) 81 | { 82 | if( array.length == 0 ) 83 | { 84 | return ""; 85 | } 86 | 87 | StringBuilder list = new StringBuilder(); 88 | list.append( array[0] ); 89 | 90 | for( int i = 1; i < array.length; i++ ) 91 | { 92 | list.append( compact ? "," : ", " ); 93 | list.append( array[i] ); 94 | } 95 | 96 | return list.toString(); 97 | } 98 | 99 | public static String []objectArrayToStringArray( Object o[] ) 100 | { 101 | String s[] = new String[o.length]; 102 | for( int i = 0; i < o.length; i++ ) 103 | { 104 | if( o[i] == null ) 105 | { 106 | s[i] = null; 107 | } 108 | else 109 | { 110 | s[i] = o[i].toString(); 111 | } 112 | } 113 | 114 | return s; 115 | } 116 | 117 | public static int []integerVectorToIntArray( List v ) 118 | { 119 | int a[] = new int[v.size()]; 120 | 121 | for( int i = 0; i < v.size(); i++ ) 122 | { 123 | a[i] = v.get( i ).intValue(); 124 | } 125 | 126 | return a; 127 | } 128 | 129 | public static List intArrayToIntegerVector( int a[] ) 130 | { 131 | List v = new ArrayList( a.length ); 132 | for( int i = 0; i < a.length; i++ ) 133 | { 134 | v.add( a[i] ); 135 | } 136 | 137 | return v; 138 | } 139 | 140 | @SuppressWarnings({ "rawtypes", "unchecked" }) 141 | public static List removeVectorNulls( List v ) 142 | { 143 | List vv = new ArrayList(); 144 | vv.addAll( v ); 145 | 146 | int rc = 0; 147 | for( int i = 0; i < v.size(); i++ ) 148 | { 149 | if( v.get( i ) == null ) 150 | { 151 | vv.remove( i - rc ); 152 | rc++; 153 | } 154 | } 155 | 156 | return vv; 157 | } 158 | 159 | /* public static Integer []integerVectorToIntegerArray( List v ) 160 | { 161 | return v.toArray( new Integer[ 0 ] ); 162 | }*/ 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/Connector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Connector.java 3 | * 4 | * Created on February 7, 2005, 12:19 AM 5 | */ 6 | 7 | package pt.evolute.utils.db; 8 | 9 | import java.sql.Connection; 10 | import java.sql.DriverManager; 11 | import java.sql.SQLException; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | import pt.evolute.utils.string.StringPlainer; 16 | 17 | /** 18 | * 19 | * @author lflores 20 | */ 21 | public class Connector 22 | { 23 | // private static final String MYSQL = "mysql"; 24 | 25 | private static final Map SCHEMAS = new HashMap(); 26 | 27 | static 28 | { 29 | // SCHEMAS.put( "postgresql", "public" ); 30 | SCHEMAS.put( "informix-sqli", "informix" ); 31 | SCHEMAS.put( "hsqldb", "PUBLIC" ); 32 | SCHEMAS.put( "sqlserver", "dbo" ); 33 | } 34 | 35 | public static Connection getConnection( String url, String user, String passwd ) 36 | throws SQLException 37 | { 38 | if( DriverProvider.loadDriverForURL( url ) ) 39 | { 40 | // System.out.println( "Driver recognized - " 41 | // + DriverManager.getDriver(url).getMajorVersion() + "/" 42 | // + DriverManager.getDriver(url).getMinorVersion() ); 43 | } 44 | else 45 | { 46 | System.out.println( "Driver NOT recognized: " + url ); 47 | } 48 | Connection con = DriverManager.getConnection( url, user, passwd ); 49 | // System.out.println( "DriverName: " + con.getMetaData().getDriverName() 50 | // + " DriverVersion: " + con.getMetaData().getDriverVersion() ); 51 | // System.out.println( "AutoComit: " + con.getAutoCommit() ); 52 | // System.out.println( "Catalog: " + getCatalog( url ) + " Schema: " + getSchema( url ) ); 53 | con.setAutoCommit( true ); 54 | return con; 55 | } 56 | 57 | // public static String getSchema( String url ) 58 | // { 59 | // /*StringTokenizer st = new StringTokenizer( url, ":", false ); 60 | // st.nextToken();*/ 61 | // String db = url.split( ":" )[ 1 ]; 62 | // String result = null; 63 | // if( SCHEMAS.containsKey( db ) ) 64 | // { 65 | // result = SCHEMAS.get( db ); 66 | // } 67 | // else 68 | // { 69 | // if( MYSQL.equals( db ) ) 70 | // { 71 | //// String dbNameAndProps = url.split( "/" )[ 3 ]; 72 | //// result = dbNameAndProps.split( "[?]" )[ 0 ]; 73 | // result = null; 74 | // } 75 | // } 76 | // return result; 77 | // } 78 | 79 | public static String getCatalog( String url ) 80 | { 81 | if( url.indexOf( "odbc" ) != -1 ) 82 | { 83 | return null; 84 | } 85 | else if( url.indexOf( "sqlserver" ) != -1 ) 86 | { 87 | String s[] = url.split( "[/;]" ); 88 | for( int n = 1; n < s.length; n++ ) 89 | { 90 | if( s[ n ].indexOf( "databaseName" ) == 0 ) 91 | { 92 | return s[ n ].split( "=" )[ 1 ]; 93 | } 94 | } 95 | return null; 96 | } 97 | else 98 | { 99 | String s[] = url.split( "/" ); 100 | String catalog = s[ s.length - 1 ].split( "\\?" )[ 0 ]; 101 | return catalog.split( ":" )[ 0 ]; 102 | } 103 | } 104 | 105 | public static String fixName( String name ) 106 | { 107 | String orig = name; 108 | /* if( name.startsWith( "expr" ) ) 109 | { 110 | System.out.println( "ERROR: " + orig + " - " + name ); 111 | new Exception().printStackTrace(); 112 | }*/ 113 | try 114 | { 115 | name = "n" + Integer.parseInt( name ); 116 | } 117 | catch( NumberFormatException ex ) 118 | { 119 | } 120 | name = name.replace( '-', '_' ); 121 | name = name.replaceAll( " ", "" ); 122 | name = StringPlainer.convertString( name ); 123 | 124 | if( name.startsWith( "expr" ) ) 125 | { 126 | new Exception( "ERROR: " + orig + " - " + name ).printStackTrace(); 127 | } 128 | 129 | return name; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/DriverProvider.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.db; 2 | 3 | import java.sql.DriverManager; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import java.util.StringTokenizer; 7 | import java.util.regex.Matcher; 8 | import java.util.regex.Pattern; 9 | 10 | public class DriverProvider 11 | { 12 | private final static Map drivers = new HashMap(); 13 | private final static Map nameRegex = new HashMap(); 14 | 15 | private static boolean driverManagerSilent = false; 16 | 17 | static 18 | { 19 | drivers.put("firebirdsql", "org.firebirdsql.jdbc.FBDriver"); 20 | drivers.put("hsqldb", "org.hsqldb.jdbcDriver"); 21 | drivers.put("informix-sqli", "com.informix.jdbc.IfxDriver"); 22 | drivers.put("jackcess", "org.tiyuk.jackcessjdbc.JackcessDriver"); 23 | drivers.put("mysql", "com.mysql.jdbc.Driver"); 24 | drivers.put("odbc", "sun.jdbc.odbc.JdbcOdbcDriver"); 25 | drivers.put("oracle", "oracle.jdbc.OracleDriver"); // oracle:thin 26 | drivers.put("postgresql", "org.postgresql.Driver"); 27 | drivers.put("rmi", "org.objectweb.rmijdbc.Driver"); 28 | drivers.put("sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver"); 29 | drivers.put("db2", "com.ibm.db2.jcc.DB2Driver"); 30 | drivers.put("as400", "com.ibm.as400.access.AS400JDBCDriver"); 31 | drivers.put("ucanaccess", "net.ucanaccess.jdbc.UcanaccessDriver"); 32 | 33 | //name parser 34 | nameRegex.put("org.postgresql.Driver", "(/+[a-zA-Z0-9_-]+[?])"); 35 | } 36 | 37 | public static String getDatabaseTypeFromUrl( String url ) 38 | { 39 | StringTokenizer st = new StringTokenizer(url, ":", false); 40 | st.nextToken(); 41 | return(st.nextToken()); 42 | } 43 | 44 | public static boolean isDriverManagerSilent() 45 | { 46 | return driverManagerSilent; 47 | } 48 | 49 | public static void setDriverManagerSilent(boolean driverManagerSilent) 50 | { 51 | DriverProvider.driverManagerSilent = driverManagerSilent; 52 | } 53 | 54 | public static boolean loadDriverForURL(String url) 55 | { 56 | boolean result = false; 57 | try 58 | { 59 | Class.forName( getDriverForURL( url ) ); 60 | result = true; 61 | } 62 | catch (ClassNotFoundException ex) 63 | { 64 | System.err.println("Couldn't find driver for URL: " + url + " class: " + getDriverForURL( url ) ); 65 | System.out.println("Couldn't find driver for URL: " + url + " class: " + getDriverForURL( url ) ); 66 | } 67 | catch( ExceptionInInitializerError ex ) 68 | { 69 | System.err.println("Couldn't find driver for URL: " + url + " class: " + getDriverForURL( url ) ); 70 | System.out.println("Couldn't find driver for URL: " + url + " class: " + getDriverForURL( url ) ); 71 | } 72 | 73 | if( isDriverManagerSilent() ) 74 | { 75 | DriverManager.setLogWriter( null ); 76 | } 77 | 78 | return result; 79 | } 80 | 81 | public static String getDriverForURL(String url) 82 | { 83 | StringTokenizer st = new StringTokenizer(url, ":", false); 84 | // if (st.hasMoreTokens()) 85 | // { 86 | st.nextToken(); 87 | // } 88 | String driver = null; 89 | // if (st.hasMoreTokens()) 90 | // { 91 | driver = drivers.get(st.nextToken()); 92 | // driver = st.nextToken(); 93 | if (driver == null) 94 | { 95 | System.err.println("Couldn't find driver for URL: " + url); 96 | System.out.println("Couldn't find driver for URL: " + url); 97 | } 98 | // } 99 | return driver; 100 | } 101 | 102 | public static String getDataBaseNameFromUrl( String url ) throws Exception 103 | { 104 | String result = null; 105 | 106 | String driver = getDriverForURL( url ); 107 | Pattern p = Pattern.compile( nameRegex.get( driver ) ); 108 | Matcher m = p.matcher( url ); 109 | if( m.find() ) 110 | { 111 | result = url.substring( m.start()+1, m.end()-1 ); 112 | } 113 | else 114 | { 115 | throw new Exception( "No Match found" ); 116 | } 117 | return result; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/Main.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer; 2 | 3 | import java.io.FileInputStream; 4 | import java.sql.SQLException; 5 | import java.util.Date; 6 | import java.util.Properties; 7 | 8 | import pt.evolute.dbtransfer.analyse.Analyser; 9 | import pt.evolute.dbtransfer.constrain.Constrainer; 10 | import pt.evolute.dbtransfer.db.beans.ConnectionDefinitionBean; 11 | import pt.evolute.dbtransfer.db.helper.HelperManager; 12 | import pt.evolute.dbtransfer.db.jdbc.JDBCConnection; 13 | import pt.evolute.dbtransfer.diff.Diff; 14 | import pt.evolute.dbtransfer.transfer.AsyncStatement; 15 | import pt.evolute.dbtransfer.transfer.Mover; 16 | 17 | /** 18 | * 19 | * @author lflores 20 | */ 21 | public class Main 22 | { 23 | public Main() 24 | throws Exception 25 | { 26 | System.out.println( "BEGIN: " + new Date() ); 27 | long start = System.currentTimeMillis(); 28 | 29 | try 30 | { 31 | ConnectionDefinitionBean srcBean = ConnectionDefinitionBean.loadBean( HelperManager.getProperties(), ConfigurationProperties.SOURCE_PROPS ); 32 | ConnectionDefinitionBean dstBean = ConnectionDefinitionBean.loadBean( HelperManager.getProperties(), ConfigurationProperties.DESTINATION_PROPS ); 33 | 34 | JDBCConnection.debug = Config.debug(); 35 | if( Config.analyse() ) 36 | { 37 | System.out.println( "Analysing" ); 38 | Analyser a = new Analyser( srcBean, dstBean ); 39 | a.cloneDB(); 40 | } 41 | if( Config.transfer() ) 42 | { 43 | if( !Config.checkDependencies() ) 44 | { 45 | AsyncStatement.PARALLEL_THREADS = Config.getParallelThreads(); 46 | } 47 | System.out.println( "Transfering" ); 48 | Mover m = new Mover( srcBean, dstBean ); 49 | try 50 | { 51 | m.moveDB(); 52 | } 53 | catch( SQLException ex ) 54 | { 55 | ex.printStackTrace( System.out ); 56 | ex.printStackTrace(); 57 | // ErrorLogger.logException( ex ); 58 | throw ex.getNextException(); 59 | } 60 | } 61 | if( Config.constrain() ) 62 | { 63 | System.out.println( "Constraining" ); 64 | Constrainer c = new Constrainer(HelperManager.getProperties(), srcBean, dstBean ); 65 | c.constrainDB(); 66 | } 67 | if( Config.diff() ) 68 | { 69 | System.out.println( "Diffing" ); 70 | Diff d = new Diff( srcBean, dstBean ); 71 | d.diffDb(); 72 | } 73 | } 74 | catch( Throwable th ) 75 | { 76 | th.printStackTrace( System.out ); 77 | } 78 | System.out.println( "END: " + new Date() ); 79 | System.out.println( "Transfer took: " + ( System.currentTimeMillis() - start ) / 1000 + " seconds" ); 80 | 81 | try 82 | { 83 | Thread.sleep( 2000 ); 84 | } 85 | catch( InterruptedException e ) 86 | {} 87 | } 88 | 89 | /** 90 | * @param args the command line arguments 91 | */ 92 | public static void main(String[] args) 93 | throws Exception 94 | { 95 | if( args.length != 1 ) 96 | { 97 | System.err.println( "Usage: " + Main.class.getName() + " " ); 98 | System.exit( 1 ); 99 | } 100 | else 101 | { 102 | try 103 | { 104 | System.out.println( "Loading props: " + args[ 0 ] ); 105 | Properties p = new Properties(); 106 | p.load( new FileInputStream( args[ 0 ] ) ); 107 | p.list( System.out ); 108 | Config.setProperties( p ); 109 | HelperManager.setProperties( p ); 110 | new Main(); 111 | } 112 | catch( Throwable th ) 113 | { 114 | th.printStackTrace(); 115 | th.printStackTrace( System.out ); 116 | try 117 | { 118 | Thread.sleep( 500 ); 119 | } 120 | catch( InterruptedException ex ) 121 | { 122 | } 123 | throw th; 124 | } 125 | } 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/analyse/Analyser.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.analyse; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | import pt.evolute.dbtransfer.Config; 7 | import pt.evolute.dbtransfer.ConfigurationProperties; 8 | import pt.evolute.dbtransfer.db.DBConnection; 9 | import pt.evolute.dbtransfer.db.DBConnector; 10 | import pt.evolute.dbtransfer.db.beans.ColumnDefinition; 11 | import pt.evolute.dbtransfer.db.beans.ConnectionDefinitionBean; 12 | import pt.evolute.dbtransfer.db.beans.TableDefinition; 13 | import pt.evolute.dbtransfer.db.helper.Helper; 14 | import pt.evolute.dbtransfer.db.helper.HelperManager; 15 | 16 | /** 17 | * 18 | * @author lflores 19 | */ 20 | public class Analyser implements ConfigurationProperties 21 | { 22 | private final TableDefinition TABLES[]; 23 | private final ConnectionDefinitionBean SRC; 24 | private final ConnectionDefinitionBean DST; 25 | private final DBConnection CON_SRC; 26 | // private final DatabaseMetaData DB_META; 27 | 28 | private final Helper SRC_TR; 29 | private final Helper DEST_TR; 30 | 31 | /** Creates a new instance of Analyser 32 | * @param props 33 | * @throws java.lang.Exception */ 34 | public Analyser( ConnectionDefinitionBean src, ConnectionDefinitionBean dst ) 35 | throws Exception 36 | { 37 | SRC = src; 38 | DST = dst; 39 | if( Config.debug() ) 40 | { 41 | System.out.println( "Analyser source: " + SRC ); 42 | System.out.println( "Analyser destination: " + DST ); 43 | } 44 | 45 | boolean ignoreEmpty = Config.ignoreEmpty(); 46 | 47 | CON_SRC = DBConnector.getConnection( SRC.getUrl(), SRC.getUser(), SRC.getPassword(), ignoreEmpty ); 48 | List v = CON_SRC.getTableList(); 49 | TABLES = v.toArray( new TableDefinition[ v.size() ] ); 50 | 51 | SRC_TR = HelperManager.getTranslator( SRC.getUrl() ); 52 | DEST_TR = HelperManager.getTranslator( DST.getUrl() ); 53 | } 54 | 55 | public void cloneDB() 56 | throws Exception 57 | { 58 | List v = new LinkedList(); 59 | List v2 = new LinkedList(); 60 | for( int i = 0; i < TABLES.length; ++i ) 61 | { 62 | List list = CON_SRC.getColumnList( TABLES[ i ] ); 63 | StringBuilder buff = new StringBuilder( "CREATE TABLE " ); 64 | buff.append( DEST_TR.getCreateTablePrefix() ); 65 | buff.append( TABLES[ i ].saneName ); 66 | buff.append( " ( " ); 67 | int j = 0; 68 | for( ColumnDefinition def: list ) 69 | { 70 | if( j != 0 ) 71 | { 72 | buff.append( ", " ); 73 | } 74 | buff.append( DEST_TR.outputName( def.name.saneName ) ); 75 | buff.append( " " ); 76 | buff.append( translate( def.sqlTypeName, def.sqlSize ) ); 77 | /* if( def.sqlSize != null ) 78 | { 79 | buff.append( "( " ); 80 | if( translate( def.sqlTypeName ).equals( "varchar" ) 81 | && def.sqlSize > 10485760 ) 82 | { 83 | def.sqlSize = 10485760; 84 | } 85 | buff.append( def.sqlSize ); 86 | buff.append( " )" ); 87 | }*/ 88 | ++j; 89 | } 90 | buff.append( ") " ); 91 | v2.add( DEST_TR.getDropTable( TABLES[ i ].toString() ) ); 92 | v.add( buff ); 93 | } 94 | 95 | DBConnection destCon = DBConnector.getConnection( DST.getUrl(), DST.getUser(), DST.getPassword(), false ); 96 | 97 | for( int i = 0; i < v.size(); ++i ) 98 | { 99 | try 100 | { 101 | // destCon.executeQuery( DEST_TR.getBegin() ); 102 | destCon.executeQuery( v2.get( i ) ); 103 | // destCon.executeQuery( DEST_TR.getCommit() ); 104 | } 105 | catch( Exception ex ) 106 | { 107 | // table didn't exist 108 | System.out.println( ex.getMessage() ); 109 | // destCon.executeQuery( DEST_TR.getRollback() ); 110 | } 111 | System.out.println( "T: " + v.get( i ) ); 112 | // destCon.executeQuery( DEST_TR.getBegin() ); 113 | destCon.executeQuery( v.get( i ).toString() ); 114 | // destCon.executeQuery( DEST_TR.getCommit() ); 115 | } 116 | } 117 | 118 | private String translate( String type, Integer size ) 119 | { 120 | return DEST_TR.outputType( SRC_TR.normalizedType( type ), size ); 121 | } 122 | } 123 | 124 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/string/StringPlainer.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.string; 2 | 3 | public class StringPlainer 4 | { 5 | public static String convertString( String s ) 6 | { 7 | return convertString( s, false, false ); 8 | } 9 | 10 | public static String convertString( String s, boolean preserveCase, 11 | boolean preserveNewLine ) 12 | { 13 | if( s != null ) 14 | { 15 | StringBuilder sb = new StringBuilder(); 16 | for( int i = 0; i < s.length(); i++ ) 17 | { 18 | Character c = convertCharacter( s.charAt( i ) ); 19 | if( c != null ) 20 | { 21 | sb.append( c ); 22 | } 23 | else if( preserveNewLine && s.charAt( i ) == '\n' ) 24 | { 25 | sb.append( s.charAt( i ) ); 26 | } 27 | } 28 | 29 | if( preserveCase ) 30 | { 31 | return sb.toString(); 32 | } 33 | else 34 | { 35 | return sb.toString().toLowerCase(); 36 | } 37 | } 38 | else 39 | { 40 | return null; 41 | } 42 | } 43 | 44 | public static Character convertCharacter( char c ) 45 | { 46 | if( c == '\'' ) // apostrofe 47 | { 48 | return ' '; 49 | } 50 | if( c >= '\u0021' && c <= '\u007e' ) 51 | { 52 | return c; 53 | } 54 | if( c >= '\u0300' && c <= '\u0360' ) 55 | { 56 | return null; 57 | } 58 | char cc = '\u0000'; 59 | 60 | switch( c ) 61 | { 62 | case ' ': 63 | { 64 | cc = ' '; 65 | break; 66 | } 67 | case '\u00c0': // A grave 68 | case '\u00c1': // A agudo 69 | case '\u00c2': // A circunflexo 70 | case '\u00c3': // A til 71 | case '\u00c4': // A trema 72 | case '\u00c5': // A bolinha 73 | { 74 | cc = 'A'; 75 | break; 76 | } 77 | case '\u00c7': // C cedilha 78 | { 79 | cc = 'C'; 80 | break; 81 | } 82 | case '\u00c8': // E grave 83 | case '\u00c9': // E agudo 84 | case '\u00ca': // E circunflexo 85 | case '\u00cb': // E trema 86 | { 87 | cc = 'E'; 88 | break; 89 | } 90 | case '\u00cc': // I grave 91 | case '\u00cd': // I agudo 92 | case '\u00ce': // I circunflexo 93 | case '\u00cf': // I trema 94 | { 95 | cc = 'I'; 96 | break; 97 | } 98 | case '\u00d1': // N til 99 | { 100 | cc = 'N'; 101 | break; 102 | } 103 | case '\u00d2': // O grave 104 | case '\u00d3': // O agudo 105 | case '\u00d4': // O circunflexo 106 | case '\u00d5': // O til 107 | case '\u00d6': // O trema 108 | { 109 | cc = 'O'; 110 | break; 111 | } 112 | case '\u00d9': // U grave 113 | case '\u00da': // U agudo 114 | case '\u00db': // U circunflexo 115 | case '\u00dc': // U trema 116 | { 117 | cc = 'U'; 118 | break; 119 | } 120 | case '\u00dd': // Y agudo 121 | { 122 | cc = 'Y'; 123 | break; 124 | } 125 | case '\u00e0': // a grave 126 | case '\u00e1': // a agudo 127 | case '\u00e2': // a circunflexo 128 | case '\u00e3': // a til 129 | case '\u00e4': // a trema 130 | case '\u00e5': // a bolinha 131 | case '\u00aa': // a pequeno usado em abreviaturas 132 | { 133 | cc = 'a'; 134 | break; 135 | } 136 | case '\u00e7': // c cedilha 137 | { 138 | cc = 'c'; 139 | break; 140 | } 141 | case '\u00e8': // e grave 142 | case '\u00e9': // e agudo 143 | case '\u00ea': // e circunflexo 144 | case '\u00eb': // e trema 145 | { 146 | cc = 'e'; 147 | break; 148 | } 149 | case '\u00ec': // i grave 150 | case '\u00ed': // i agudo 151 | case '\u00ee': // i circunflexo 152 | case '\u00ef': // i trema 153 | { 154 | cc = 'i'; 155 | break; 156 | } 157 | case '\u00f1': // n til 158 | { 159 | cc = 'n'; 160 | break; 161 | } 162 | case '\u00f2': // o grave 163 | case '\u00f3': // o agudo 164 | case '\u00f4': // o circunflexo 165 | case '\u00f5': // o til 166 | case '\u00f6': // o trema 167 | { 168 | cc = 'o'; 169 | break; 170 | } 171 | case '\u00f9': // u grave 172 | case '\u00fa': // u agudo 173 | case '\u00fb': // u circunflexo 174 | case '\u00fc': // u trema 175 | { 176 | cc = 'u'; 177 | break; 178 | } 179 | case '\u00fd': // y agudo 180 | case '\u00ff': // y trema 181 | { 182 | cc = 'y'; 183 | break; 184 | } 185 | case '\u00ba': // o pequeno usado em abreviaturas 186 | { 187 | cc = '.'; 188 | break; 189 | } 190 | default: 191 | { 192 | return ' '; 193 | } 194 | } 195 | 196 | return cc; 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | pt.evolute.dbtransfer 8 | dbtransfer 9 | 1.0-SNAPSHOT 10 | jar 11 | 12 | DBTransfer 13 | https://github.com/evolute-pt/dbtransfer 14 | 15 | 16 | UTF-8 17 | 1.8 18 | 1.8 19 | 20 | 21 | 22 | 23 | com.healthmarketscience.jackcess 24 | jackcess 25 | 4.0.1 26 | 27 | 28 | 29 | net.sf.ucanaccess 30 | ucanaccess 31 | 5.0.1 32 | runtime 33 | 34 | 35 | mysql 36 | mysql-connector-java 37 | 8.0.28 38 | runtime 39 | 40 | 41 | net.sf.jt400 42 | jt400 43 | 10.7 44 | runtime 45 | 46 | 47 | commons-logging 48 | commons-logging 49 | 1.1.3 50 | runtime 51 | 52 | 53 | commons-lang 54 | commons-lang 55 | 2.6 56 | runtime 57 | 58 | 59 | org.postgresql 60 | postgresql 61 | 42.3.4 62 | runtime 63 | 64 | 65 | net.sourceforge.jtds 66 | jtds 67 | 1.3.1 68 | 69 | 70 | com.oracle.database.jdbc 71 | ojdbc10 72 | 19.14.0.0 73 | true 74 | 75 | 76 | com.microsoft.sqlserver 77 | mssql-jdbc 78 | 10.2.0.jre8 79 | 80 | 81 | 82 | 83 | 84 | 85 | org.apache.maven.plugins 86 | maven-jar-plugin 87 | 2.4 88 | 89 | 90 | 91 | true 92 | pt.evolute.dbtransfer.Main 93 | 94 | 95 | 96 | 97 | 98 | maven-dependency-plugin 99 | 2.8 100 | 101 | 102 | copy-dependencies 103 | package 104 | 105 | copy-dependencies 106 | 107 | 108 | ${project.build.directory} 109 | false 110 | false 111 | true 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/dbmodel/DBTable.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.dbmodel; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import pt.evolute.dbtransfer.Config; 11 | import pt.evolute.utils.object.DefaultLightPropertyObject; 12 | import pt.evolute.utils.tables.ColumnizedObject; 13 | 14 | /** 15 | * 16 | * @author lflores 17 | */ 18 | 19 | public class DBTable extends DefaultLightPropertyObject 20 | implements ColumnizedObject, Cloneable 21 | { 22 | public static final String NAME = "NAME"; 23 | private final ModelProvider provider; 24 | protected List importedReferences = null; 25 | protected List exportedReferences = null; 26 | protected List hierarchys = null; 27 | protected List components = null; 28 | protected List columns = null; 29 | protected List primaryKey = null; 30 | 31 | /** Creates a new instance of DBTable */ 32 | public DBTable( ModelProvider provider ) 33 | { 34 | super( new String[] { NAME }, false ); 35 | this.provider = provider; 36 | } 37 | 38 | public List getImportedForeignKeys() 39 | throws Exception 40 | { 41 | if( importedReferences == null ) 42 | { 43 | importedReferences = Collections.unmodifiableList( provider.getImportedKeysForTable( this ) ); 44 | } 45 | return importedReferences; 46 | } 47 | 48 | public List getExportedForeignKeys() 49 | throws Exception 50 | { 51 | if( exportedReferences == null ) 52 | { 53 | exportedReferences = Collections.unmodifiableList( provider.getExportedKeysForTable( this ) ); 54 | } 55 | return exportedReferences; 56 | } 57 | 58 | public List getPrimaryKey() 59 | throws Exception 60 | { 61 | if( primaryKey == null ) 62 | { 63 | primaryKey = Collections.unmodifiableList( provider.getPrimaryKeyForTable( this ) ); 64 | } 65 | return primaryKey; 66 | } 67 | 68 | @SuppressWarnings("unchecked") 69 | public Object getValue( int col ) 70 | { 71 | return get( getPropertyNames()[ col ] ); 72 | } 73 | 74 | public List getHierarchys() 75 | throws Exception 76 | { 77 | if( hierarchys == null ) 78 | { 79 | hierarchys = Collections.unmodifiableList( provider.getHierarchysForTable( this ) ); 80 | } 81 | return hierarchys; 82 | } 83 | 84 | public List getColumns() 85 | throws Exception 86 | { 87 | if( columns == null ) 88 | { 89 | columns = Collections.unmodifiableList( provider.getColumnsForTable( this ) ); 90 | } 91 | return columns; 92 | } 93 | 94 | public List getColumnsNoPK() 95 | throws Exception 96 | { 97 | Map pk = new HashMap(); 98 | for( DBColumn c: getPrimaryKey() ) 99 | { 100 | pk.put( c, c ); 101 | } 102 | List cols = new LinkedList(); 103 | for( DBColumn c: getColumns() ) 104 | { 105 | if( !pk.containsKey( c ) ) 106 | { 107 | cols.add( c ); 108 | } 109 | } 110 | return cols; 111 | } 112 | 113 | public int getNumberColumns() 114 | throws Exception 115 | { 116 | return getColumns().size(); 117 | } 118 | 119 | public List getComponents() 120 | throws Exception 121 | { 122 | if( components == null ) 123 | { 124 | getHierarchys(); 125 | components = new ArrayList(); 126 | for( DBHierarchy hierarchy: hierarchys ) 127 | { 128 | DBTable table = hierarchy.getTables()[ 1 ]; 129 | if( !components.contains( table ) ) 130 | { 131 | components.add( table ); 132 | } 133 | } 134 | components = Collections.unmodifiableList( components ); 135 | } 136 | return components; 137 | } 138 | 139 | @Override 140 | public Object clone() 141 | { 142 | DBTable table = new DBTable( provider ); 143 | table.setMapData( getMapData() ); 144 | table.importedReferences = importedReferences; 145 | table.exportedReferences = exportedReferences; 146 | table.hierarchys = hierarchys; 147 | table.components = components; 148 | return table; 149 | } 150 | 151 | @Override 152 | public String toString() 153 | { 154 | return ( String ) get( NAME ); 155 | } 156 | 157 | public String getSaneName() 158 | { 159 | return ( ( String ) get( NAME ) ).toLowerCase(); 160 | } 161 | 162 | public String getDestinationName() 163 | { 164 | return Config.getDestinationTablePrefix() + toString(); 165 | } 166 | 167 | @Override 168 | public boolean equals( Object o ) 169 | { 170 | boolean eq = o instanceof DBTable; 171 | if( eq ) 172 | { 173 | eq = toString().equals( ((DBTable)o).toString() ); 174 | } 175 | return eq; 176 | } 177 | 178 | @Override 179 | public int hashCode() 180 | { 181 | int hash = 3; 182 | hash = 53 * ( hash + (this.toString() != null ? this.toString().hashCode() : 0) ); 183 | return hash; 184 | } 185 | } 186 | 187 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/helper/HsqlDBServerHelper.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.helper; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import pt.evolute.dbtransfer.db.DBConnection; 7 | import pt.evolute.dbtransfer.db.beans.Name; 8 | import pt.evolute.utils.db.DBConstants; 9 | 10 | public class HsqlDBServerHelper extends NullHelper 11 | { 12 | private static final Map OUTPUT = new HashMap(); 13 | // private static final Map RESERVED = new HashMap(); 14 | private static final Map NORMALIZE = new HashMap(); 15 | private static final Map DEFAULTS = new HashMap(); 16 | private static final Map NORMALIZE_DEFAULTS = new HashMap(); 17 | 18 | static 19 | { 20 | 21 | } 22 | 23 | private static HsqlDBServerHelper translator = null; 24 | 25 | private HsqlDBServerHelper() 26 | { 27 | // System.out.println( "Oracle helper - setting double slash on UnicodeChecker" ); 28 | // UnicodeChecker.setUseDoubleSlash( true ); 29 | } 30 | 31 | public static HsqlDBServerHelper getTranslator() 32 | { 33 | if( translator == null ) 34 | { 35 | translator = new HsqlDBServerHelper(); 36 | } 37 | return translator; 38 | } 39 | 40 | @Override 41 | public String outputType( String type, Integer size ) 42 | { 43 | String output = OUTPUT.get( type.toLowerCase() ); 44 | if( output == null ) 45 | { 46 | output = type; 47 | } 48 | 49 | return output.toUpperCase(); 50 | } 51 | 52 | @Override 53 | public String outputName( String name ) 54 | { 55 | if( name.contains( " " ) ) 56 | { 57 | name = name.replace( ' ', '_' ); 58 | } 59 | if( name.contains( "." ) ) 60 | { 61 | name = name.replace( '.', '_' ); 62 | } 63 | // name = StringPlainer.convertString( name ); 64 | // if( RESERVED.containsKey( name ) ) 65 | // { 66 | // name = "\"" + name + "\""; 67 | // } 68 | if( !name.equals( name.toUpperCase() ) ) 69 | { 70 | name = "\"" + name + "\""; 71 | } 72 | return name; 73 | } 74 | 75 | @Override 76 | public String normalizedType( String type ) 77 | { 78 | String normalize = NORMALIZE.get( type.toLowerCase() ); 79 | if( normalize == null ) 80 | { 81 | normalize = type; 82 | } 83 | return normalize.toUpperCase(); 84 | } 85 | 86 | @Override 87 | public void fixSequences( DBConnection con, String table, String typeName, String column ) 88 | throws Exception 89 | { 90 | 91 | } 92 | 93 | @Override 94 | public String normalizeValue( String value ) 95 | { 96 | if( value != null ) 97 | { 98 | } 99 | return value; 100 | } 101 | 102 | @Override 103 | public void setDefaultValue( DBConnection con, String table, String typeName, String column, String value ) 104 | throws Exception 105 | { 106 | if( DEFAULTS.containsKey( value ) ) 107 | { 108 | value = DEFAULTS.get( value ); 109 | } 110 | if( value != null && !value.isEmpty() ) 111 | { 112 | try 113 | { 114 | super.setDefaultValue( con, table, typeName, column, value ); 115 | } 116 | catch( Exception ex ) 117 | { 118 | System.out.println( "type: <" + typeName + "> value: <" + value + ">" ); 119 | throw ex; 120 | } 121 | } 122 | } 123 | 124 | @Override 125 | public int translateType( int type ) 126 | { 127 | int pType = type; 128 | switch ( type ) 129 | { 130 | default: 131 | break; 132 | } 133 | return pType; 134 | } 135 | 136 | @Override 137 | public String normalizeDefault( String str ) 138 | { 139 | String norm = NORMALIZE_DEFAULTS.get( str ); 140 | if( norm == null ) 141 | { 142 | norm = str; 143 | } 144 | return norm; 145 | } 146 | 147 | @Override 148 | public void initConnection( DBConnection con) throws Exception 149 | { 150 | // JDBCConnection con2 = ( JDBCConnection )con; 151 | // con2.executeQuery( "CREATE FUNCTION md5(VARBINARY(128))\n" 152 | // + "RETURNS VARBINARY(226)\n" 153 | // + "LANGUAGE JAVA\n" 154 | // + "DETERMINISTIC \n" 155 | // + "NO SQL\n" 156 | // + "EXTERNAL NAME 'CLASSPATH:org.hsqldb.lib.MD5.digest'\n" 157 | // + ";" ); 158 | } 159 | 160 | @Override 161 | public boolean isTableValid( Name name ) 162 | { 163 | return !name.saneName.contains( "==" ); 164 | } 165 | 166 | @Override 167 | public String getType() { 168 | return DBConstants.DB_HSQL; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/helper/OracleServerHelper.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.helper; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import pt.evolute.dbtransfer.db.DBConnection; 7 | import pt.evolute.dbtransfer.db.beans.Name; 8 | import pt.evolute.dbtransfer.db.jdbc.JDBCConnection; 9 | 10 | public class OracleServerHelper extends NullHelper 11 | { 12 | private static final Map OUTPUT = new HashMap(); 13 | // private static final Map RESERVED = new HashMap(); 14 | private static final Map NORMALIZE = new HashMap(); 15 | private static final Map DEFAULTS = new HashMap(); 16 | private static final Map NORMALIZE_DEFAULTS = new HashMap(); 17 | 18 | static 19 | { 20 | OUTPUT.put( "varchar", "varchar2" ); 21 | OUTPUT.put( "numeric", "number" ); 22 | OUTPUT.put( "text", "nclob" ); 23 | 24 | NORMALIZE.put( "varchar2", "varchar" ); 25 | NORMALIZE.put( "number", "numeric" ); 26 | NORMALIZE.put( "long", "text" ); 27 | NORMALIZE.put( "long raw", "blob" ); 28 | } 29 | 30 | private static OracleServerHelper translator = null; 31 | 32 | private OracleServerHelper() 33 | { 34 | // System.out.println( "Oracle helper - setting double slash on UnicodeChecker" ); 35 | // UnicodeChecker.setUseDoubleSlash( true ); 36 | } 37 | 38 | public static OracleServerHelper getTranslator() 39 | { 40 | if( translator == null ) 41 | { 42 | translator = new OracleServerHelper(); 43 | } 44 | return translator; 45 | } 46 | 47 | @Override 48 | public String outputType( String type, Integer size ) 49 | { 50 | String output = OUTPUT.get( type.toLowerCase() ); 51 | if( output == null ) 52 | { 53 | output = type; 54 | } 55 | 56 | return output.toUpperCase(); 57 | } 58 | 59 | @Override 60 | public String outputName( String name ) 61 | { 62 | if( name.contains( " " ) ) 63 | { 64 | name = name.replace( ' ', '_' ); 65 | } 66 | if( name.contains( "." ) ) 67 | { 68 | name = name.replace( '.', '_' ); 69 | } 70 | // name = StringPlainer.convertString( name ); 71 | // if( RESERVED.containsKey( name ) ) 72 | // { 73 | // name = "\"" + name + "\""; 74 | // } 75 | if( !name.equals( name.toUpperCase() ) ) 76 | { 77 | name = "\"" + name + "\""; 78 | } 79 | return name; 80 | } 81 | 82 | @Override 83 | public String normalizedType( String type ) 84 | { 85 | String normalize = NORMALIZE.get( type.toLowerCase() ); 86 | if( normalize == null ) 87 | { 88 | normalize = type; 89 | } 90 | return normalize.toUpperCase(); 91 | } 92 | 93 | @Override 94 | public void fixSequences( DBConnection con, String table, String typeName, String column ) 95 | throws Exception 96 | { 97 | 98 | } 99 | 100 | @Override 101 | public String normalizeValue( String value ) 102 | { 103 | if( value != null ) 104 | { 105 | } 106 | return value; 107 | } 108 | 109 | @Override 110 | public void setDefaultValue( DBConnection con, String table, String typeName, String column, String value ) 111 | throws Exception 112 | { 113 | if( DEFAULTS.containsKey( value ) ) 114 | { 115 | value = DEFAULTS.get( value ); 116 | } 117 | if( value != null && !value.isEmpty() ) 118 | { 119 | try 120 | { 121 | super.setDefaultValue( con, table, typeName, column, value ); 122 | } 123 | catch( Exception ex ) 124 | { 125 | System.out.println( "type: <" + typeName + "> value: <" + value + ">" ); 126 | throw ex; 127 | } 128 | } 129 | } 130 | 131 | @Override 132 | public int translateType( int type ) 133 | { 134 | int pType = type; 135 | switch ( type ) 136 | { 137 | default: 138 | break; 139 | } 140 | return pType; 141 | } 142 | 143 | @Override 144 | public String normalizeDefault( String str ) 145 | { 146 | String norm = NORMALIZE_DEFAULTS.get( str ); 147 | if( norm == null ) 148 | { 149 | norm = str; 150 | } 151 | return norm; 152 | } 153 | 154 | @Override 155 | public void initConnection( DBConnection con) throws Exception 156 | { 157 | JDBCConnection con2 = ( JDBCConnection )con; 158 | con2.executeQuery( "ALTER SESSION SET CURRENT_SCHEMA=" + con2.getSchema() /*+ ";"*/ ); 159 | con2.executeQuery( "ALTER SESSION SET nls_date_format='RR.MM.DD'" ); 160 | } 161 | 162 | @Override 163 | public boolean isTableValid( Name name ) 164 | { 165 | return !name.saneName.contains( "==" ); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/jackcess/JackcessConnection.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.jackcess; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.sql.PreparedStatement; 6 | import java.util.HashMap; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.Set; 11 | 12 | import com.healthmarketscience.jackcess.Database; 13 | import com.healthmarketscience.jackcess.DatabaseBuilder; 14 | import com.healthmarketscience.jackcess.Index; 15 | 16 | import pt.evolute.dbtransfer.db.DBConnection; 17 | import pt.evolute.dbtransfer.db.beans.ColumnDefinition; 18 | import pt.evolute.dbtransfer.db.beans.ForeignKeyDefinition; 19 | import pt.evolute.dbtransfer.db.beans.PrimaryKeyDefinition; 20 | import pt.evolute.dbtransfer.db.beans.TableDefinition; 21 | import pt.evolute.dbtransfer.db.beans.UniqueDefinition; 22 | import pt.evolute.dbtransfer.db.helper.Helper; 23 | import pt.evolute.dbtransfer.db.jackcess.beans.AccessTableDefinition; 24 | import pt.evolute.utils.arrays.Virtual2DArray; 25 | import pt.evolute.utils.dbmodel.DBTable; 26 | 27 | /** 28 | * 29 | * @author lflores 30 | */ 31 | public class JackcessConnection implements DBConnection { 32 | 33 | private final Database db; 34 | 35 | private final List TABLES_LIST = new LinkedList(); 36 | private final Map TABLES_MAP = new HashMap(); 37 | private final boolean ignoreEmpty; 38 | 39 | public JackcessConnection(String url, String user, String pass, boolean onlyNotEmpty) 40 | throws Exception { 41 | db = DatabaseBuilder.open(new File(url.substring( 9 ))); 42 | ignoreEmpty = onlyNotEmpty; 43 | } 44 | 45 | public List getTableList() 46 | throws Exception { 47 | if (TABLES_LIST.isEmpty()) { 48 | Set set = db.getTableNames(); 49 | System.out.println("Database has " + set.size() + " tables"); 50 | for (String str : set) { 51 | TableDefinition n = new TableDefinition(str); 52 | if (ignoreEmpty && getRowCount(n) == 0) { 53 | continue; 54 | } 55 | TABLES_LIST.add(n); 56 | } 57 | } 58 | return TABLES_LIST; 59 | } 60 | 61 | public AccessTableDefinition getTableDefinition(TableDefinition table) 62 | throws IOException { 63 | AccessTableDefinition t = TABLES_MAP.get(table); 64 | if (t == null) { 65 | com.healthmarketscience.jackcess.Table tb = db.getTable(table.originalName); 66 | if (tb != null) { 67 | t = new AccessTableDefinition( /*this,*/tb); 68 | TABLES_MAP.put(table, t); 69 | } 70 | } 71 | return t; 72 | } 73 | 74 | public List getColumnList(TableDefinition table) throws Exception { 75 | return getTableDefinition(table).getColumns(); 76 | } 77 | 78 | public Virtual2DArray executeQuery(String sql) throws Exception { 79 | throw new UnsupportedOperationException("Not supported yet."); 80 | } 81 | 82 | public PrimaryKeyDefinition getPrimaryKey(TableDefinition table) throws Exception { 83 | List cols = getTableDefinition(table).getPrimaryKeys(); 84 | PrimaryKeyDefinition pk = new PrimaryKeyDefinition(); 85 | pk.name = table + "_" + "pk"; 86 | pk.columns.addAll(cols); 87 | return pk; 88 | } 89 | 90 | public List getForeignKeyList(TableDefinition table) throws Exception { 91 | return getTableDefinition(table).getForeignKeys(); 92 | } 93 | 94 | public Virtual2DArray getFullTable(TableDefinition table) throws Exception { 95 | return new Jackcess2DArray(db.getTable(table.originalName)); 96 | } 97 | 98 | public PreparedStatement prepareStatement(String sql) throws Exception { 99 | throw new UnsupportedOperationException("Not supported yet."); 100 | } 101 | 102 | @Override 103 | public List getSortedTables() throws Exception { 104 | throw new RuntimeException("Not implemented yet!!!!"); 105 | } 106 | 107 | @Override 108 | public List getUniqueList(TableDefinition table) 109 | throws Exception { 110 | // table = table.toLowerCase(); 111 | List list = new LinkedList(); 112 | for (Index idx : db.getTable(table.originalName).getIndexes()) { 113 | if (idx.isUnique()) { 114 | UniqueDefinition uniq = new UniqueDefinition(idx.getName(), table); 115 | for (Index.Column col : idx.getColumns()) { 116 | uniq.columns.add(col.getName().toLowerCase()); 117 | } 118 | } 119 | } 120 | return list; 121 | } 122 | 123 | @Override 124 | public int getRowCount(TableDefinition table) throws Exception { 125 | return db.getTable(table.originalName).getRowCount(); 126 | } 127 | 128 | public Helper getHelper() { 129 | throw new UnsupportedOperationException("Not supported yet."); 130 | } 131 | 132 | @Override 133 | public void addColumnToTable(TableDefinition table, ColumnDefinition col) throws Exception { 134 | throw new UnsupportedOperationException("Not supported yet."); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/db/ForeignKeyMetadataConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ForeignKeyMetadataConstants.java 3 | * 4 | * Created on 5 de Dezembro de 2006, 18:11 5 | * 6 | * To change this template, choose Tools | Template Manager 7 | * and open the template in the editor. 8 | */ 9 | 10 | package pt.evolute.utils.db; 11 | 12 | /** 13 | * 14 | * @author fpalma 15 | */ 16 | public interface ForeignKeyMetadataConstants 17 | { 18 | public static final String PKTABLE_CAT = "PKTABLE_CAT"; 19 | public static final String PKTABLE_SCHEM = "PKTABLE_SCHEM"; 20 | public static final String PKTABLE_NAME = "PKTABLE_NAME"; 21 | public static final String PKCOLUMN_NAME = "PKCOLUMN_NAME"; 22 | public static final String FKTABLE_CAT = "FKTABLE_CAT"; 23 | public static final String FKTABLE_SCHEM = "FKTABLE_SCHEM"; 24 | public static final String FKTABLE_NAME = "FKTABLE_NAME"; 25 | public static final String FKCOLUMN_NAME = "FKCOLUMN_NAME"; 26 | public static final String KEY_SEQ = "KEY_SEQ"; 27 | public static final String UPDATE_RULE = "UPDATE_RULE"; 28 | public static final String DELETE_RULE = "DELETE_RULE"; 29 | public static final String FK_NAME = "FK_NAME"; 30 | public static final String PK_NAME = "PK_NAME"; 31 | public static final String DEFERRABILITY = "DEFERRABILITY"; 32 | 33 | public static final int INDEX_PKTABLE_CAT = 1; 34 | public static final int INDEX_PKTABLE_SCHEM = 2; 35 | public static final int INDEX_PKTABLE_NAME = 3; 36 | public static final int INDEX_PKCOLUMN_NAME = 4; 37 | public static final int INDEX_FKTABLE_CAT = 5; 38 | public static final int INDEX_FKTABLE_SCHEM = 6; 39 | public static final int INDEX_FKTABLE_NAME = 7; 40 | public static final int INDEX_FKCOLUMN_NAME = 8; 41 | public static final int INDEX_KEY_SEQ = 9; 42 | public static final int INDEX_UPDATE_RULE = 10; 43 | public static final int INDEX_DELETE_RULE = 11; 44 | public static final int INDEX_FK_NAME = 12; 45 | public static final int INDEX_PK_NAME = 13; 46 | public static final int INDEX_DEFERRABILITY = 14; 47 | 48 | public static final String DESCRIPTIONS[] = 49 | new String[]{ "", 50 | PKTABLE_CAT, 51 | PKTABLE_SCHEM, 52 | PKTABLE_NAME, 53 | PKCOLUMN_NAME, 54 | FKTABLE_CAT, 55 | FKTABLE_SCHEM, 56 | FKTABLE_NAME, 57 | FKCOLUMN_NAME, 58 | KEY_SEQ, 59 | UPDATE_RULE, 60 | DELETE_RULE, 61 | FK_NAME, 62 | PK_NAME, 63 | DEFERRABILITY 64 | }; 65 | 66 | public static final String TYPES[] = 67 | new String[]{ "", 68 | "String", 69 | "String", 70 | "String", 71 | "String", 72 | "String", 73 | "String", 74 | "String", 75 | "String", 76 | "short", 77 | "short", 78 | "short", 79 | "String", 80 | "String", 81 | "short" 82 | }; 83 | 84 | public static final boolean IS_USED[] = 85 | new boolean[]{ false, 86 | true, 87 | true, 88 | true, 89 | true, 90 | true, 91 | true, 92 | true, 93 | true, 94 | true, 95 | true, 96 | true, 97 | true, 98 | true, 99 | true 100 | }; 101 | 102 | public static final boolean IS_CLASS[] = 103 | new boolean[]{ false, 104 | true, 105 | true, 106 | true, 107 | true, 108 | true, 109 | true, 110 | true, 111 | true, 112 | false, 113 | false, 114 | false, 115 | true, 116 | true, 117 | false 118 | }; 119 | 120 | public static final Class CLASS_FOR_TYPE[] = 121 | new Class[]{ null, 122 | String.class, 123 | String.class, 124 | String.class, 125 | String.class, 126 | String.class, 127 | String.class, 128 | String.class, 129 | String.class, 130 | Short.class, 131 | Short.class, 132 | Short.class, 133 | String.class, 134 | String.class, 135 | Short.class 136 | }; 137 | 138 | public static final String COMMENTS[] = 139 | new String[]{ "", 140 | "primary key table catalog (may be null)", 141 | "primary key table schema (may be null)", 142 | "primary key table name", 143 | "primary key column name", 144 | "foreign key table catalog (may be null)", 145 | "foreign key table schema (may be null)", 146 | "foreign key table name", 147 | "foreign key column name", 148 | "sequence number within a foreign key", 149 | "What happens to a foreign key when the primary key is updated:" 150 | + "\n\t* importedNoAction - do not allow update of primary key if it has been imported" 151 | + "\n\t* * importedKeyCascade - change imported key to agree with primary key update" 152 | + "\n\t* * importedKeySetNull - change imported key to NULL if its primary key has been updated" 153 | + "\n\t* * importedKeySetDefault - change imported key to default values if its primary key has been updated" 154 | + "\n\t* * importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility) ", 155 | "What happens to the foreign key when primary is deleted." 156 | + "\n\t* importedKeyNoAction - do not allow delete of primary key if it has been imported" 157 | + "\n\t* importedKeyCascade - delete rows that import a deleted key" 158 | + "\n\t* importedKeySetNull - change imported key to NULL if its primary key has been deleted" 159 | + "\n\t* importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)" 160 | + "\n\t* importedKeySetDefault - change imported key to default if its primary key has been deleted ", 161 | "foreign key name (may be null)", 162 | "primary key name (may be null)", 163 | "can the evaluation of foreign key constraints be deferred until commit" 164 | + "\n\t* importedKeyInitiallyDeferred - see SQL92 for definition" 165 | + "\n\t* importedKeyInitiallyImmediate - see SQL92 for definition" 166 | + "\n\t* importedKeyNotDeferrable - see SQL92 for definition " 167 | }; 168 | } 169 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/Update.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.SQLException; 5 | 6 | import pt.evolute.utils.arrays.Virtual2DArray; 7 | import pt.evolute.utils.db.ExecuterProvider; 8 | import pt.evolute.utils.jdbc.StatementExecuterFactory; 9 | import pt.evolute.utils.sql.backend.Backend; 10 | import pt.evolute.utils.sql.backend.BackendProvider; 11 | 12 | public class Update implements UpdateQuery 13 | { 14 | private String iStatement = null; 15 | private boolean unicodeFullStatement = false; 16 | // private boolean strange = false; 17 | 18 | private String iTableName; 19 | private Assignment iAssignments[]; 20 | private String iFromTables[]; 21 | private Expression iWhere; 22 | 23 | private Virtual2DArray res = null; 24 | 25 | private int batchSize = -1; 26 | 27 | private Backend backend = null; 28 | 29 | public Update( String tableName, 30 | Assignment []assignments, 31 | String fromTables[], 32 | Expression whereExpression ) 33 | { 34 | iTableName = tableName; 35 | iAssignments = assignments; 36 | iFromTables = fromTables; 37 | iWhere = whereExpression; 38 | } 39 | 40 | public Update( String tableName, 41 | Assignment []assignments, 42 | Expression whereExpression ) 43 | { 44 | this( tableName, assignments, null, whereExpression ); 45 | } 46 | 47 | public Update( String updateQuery ) 48 | { 49 | iStatement = updateQuery; 50 | // strange = true; 51 | } 52 | 53 | public void setUnicodeFullStatement( boolean translate ) 54 | { 55 | unicodeFullStatement = translate; 56 | } 57 | 58 | @Override 59 | public String toString() 60 | { 61 | if( iStatement != null ) 62 | { 63 | // TODO - called too many times! 64 | // System.out.println( "Fix UPDATE to: " + getBackend().portSyntax( iStatement ) ); 65 | return toUnicode( getBackend().portSyntax( iStatement ) ).toString(); 66 | } 67 | if( iTableName == null || iAssignments == null || iAssignments.length == 0 ) 68 | { 69 | return ""; 70 | } 71 | StringBuilder statement = new StringBuilder( "UPDATE " ); 72 | statement.append( iTableName ); 73 | statement.append( " SET " ); 74 | for( int n = 0; n < iAssignments.length - 1; n++ ) 75 | { 76 | iAssignments[ n ].setBackend( getBackend() ); 77 | // iAssignments[ n ].getOperand().setUnicode( unicodeFullStatement ); 78 | statement.append( iAssignments[ n ] ); 79 | statement.append( ", " ); 80 | } 81 | // iAssignments[ iAssignments.length - 1 ].getOperand().setUnicode( unicodeFullStatement ); 82 | iAssignments[ iAssignments.length - 1 ].setBackend( getBackend() ); 83 | statement.append( iAssignments[ iAssignments.length - 1 ] ); 84 | statement.append( " " ); 85 | if( iFromTables != null && iFromTables.length > 0 ) 86 | { 87 | statement.append( "FROM " ); 88 | statement.append( iFromTables[ 0 ] ); 89 | for( int i = 1; i < iFromTables.length; ++i ) 90 | { 91 | statement.append( ", " ); 92 | statement.append( iFromTables[ i ] ); 93 | } 94 | statement.append( " " ); 95 | } 96 | if( iWhere != null ) 97 | { 98 | iWhere.setBackend( getBackend() ); 99 | String wClause = iWhere.toString(); 100 | if( !wClause.isEmpty() ) 101 | { 102 | statement.append( "WHERE " ); 103 | statement.append( wClause ); 104 | statement.append( ";" ); 105 | } 106 | } 107 | return toUnicode( getBackend().portSyntax( statement ) ).toString(); 108 | } 109 | 110 | private CharSequence toUnicode( CharSequence str ) 111 | { 112 | if( unicodeFullStatement ) 113 | { 114 | return backend.escapeUnicode( str ); 115 | } 116 | else 117 | { 118 | return str.toString(); 119 | } 120 | } 121 | 122 | @Override 123 | public void execute() 124 | throws Exception 125 | { 126 | res = StatementExecuterFactory.executeUpdateStatementWithCursor( this.toString(), this ); 127 | } 128 | 129 | @Override 130 | public void execute( ExecuterProvider provider ) 131 | throws Exception 132 | { 133 | res = provider.getExecuter().executeQuery( this ); 134 | } 135 | 136 | @Override 137 | public Object[][] getObjects() 138 | { 139 | Virtual2DArray resArray = getCursorObjects(); 140 | if( resArray == null ) 141 | { 142 | return null; 143 | } 144 | return resArray.getObjects(); 145 | } 146 | 147 | @Override 148 | public Virtual2DArray getCursorObjects() 149 | { 150 | return res; 151 | } 152 | 153 | @Override 154 | public String[] getBatch() 155 | { 156 | String updates[] = new String[ batchSize ]; 157 | for( int i = 0; i < batchSize; ++i ) 158 | { 159 | for( int j = 0; j < iAssignments.length; ++j ) 160 | { 161 | if( iAssignments[ j ].isBatch() ) 162 | { 163 | iAssignments[ j ].currentBatch( i ); 164 | } 165 | } 166 | updates[ i ] = toString(); 167 | } 168 | return updates; 169 | } 170 | 171 | @Override 172 | public boolean isBatch() 173 | { 174 | if( iAssignments == null ) 175 | { 176 | return false; 177 | } 178 | for( int i = 0; i < iAssignments.length; ++i ) 179 | { 180 | if( iAssignments[ i ].isBatch() ) 181 | { 182 | batchSize = iAssignments[ i ].getBatchSize(); 183 | return true; 184 | } 185 | } 186 | return false; 187 | } 188 | 189 | @Override 190 | public void fillParameters(Object stm) 191 | throws SQLException 192 | { 193 | int i = 1; 194 | PreparedStatement pstm = ( PreparedStatement )stm; 195 | if( iAssignments != null ) 196 | { 197 | for( Assignment a: iAssignments ) 198 | { 199 | if( a.getOperand().getInnerObject() instanceof byte[] ) 200 | { 201 | pstm.setBytes( i, ( byte[] )a.getOperand().getInnerObject() ); 202 | ++i; 203 | } 204 | } 205 | } 206 | } 207 | 208 | @Override 209 | public void setBackend( Backend backend ) 210 | { 211 | this.backend = backend; 212 | } 213 | 214 | protected Backend getBackend() 215 | { 216 | if( backend == null ) 217 | { 218 | new Exception( "NO BACKEND!!!!" ).printStackTrace( System.out ); 219 | setBackend( BackendProvider.getDefaultBackend() ); 220 | } 221 | return backend; 222 | } 223 | 224 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/dbtransfer/db/helper/NullHelper.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.dbtransfer.db.helper; 2 | 3 | import java.sql.Blob; 4 | import java.sql.PreparedStatement; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | import java.sql.Time; 8 | import java.sql.Timestamp; 9 | import java.sql.Types; 10 | 11 | import pt.evolute.dbtransfer.db.DBConnection; 12 | import pt.evolute.dbtransfer.db.beans.Name; 13 | 14 | public class NullHelper implements Helper 15 | { 16 | private static NullHelper translator = null; 17 | 18 | protected NullHelper() 19 | { 20 | } 21 | 22 | public static NullHelper getTranslator() 23 | { 24 | if( translator == null ) 25 | { 26 | translator = new NullHelper(); 27 | } 28 | return translator; 29 | } 30 | 31 | @Override 32 | public String outputType( String type, Integer size ) 33 | { 34 | if( size != null ) 35 | { 36 | type = type + "( " + size + ")"; 37 | } 38 | return type; 39 | } 40 | 41 | @Override 42 | public String outputName( String name ) 43 | { 44 | return name; 45 | } 46 | 47 | @Override 48 | public String normalizedType( String type ) 49 | { 50 | return type; 51 | } 52 | 53 | @Override 54 | public String preLoadSetup( String table ) 55 | { 56 | return null; 57 | } 58 | 59 | @Override 60 | public String postLoadSetup( String table ) 61 | { 62 | return null; 63 | } 64 | 65 | public void fixSequences( DBConnection con, String table, String typeName, String column ) 66 | throws Exception 67 | { 68 | } 69 | 70 | public void setDefaultValue( DBConnection con, String table, String typeName, String column, String value ) 71 | throws Exception 72 | { 73 | StringBuilder buff = new StringBuilder("ALTER TABLE "); 74 | buff.append( table ); 75 | buff.append(" ALTER COLUMN "); 76 | buff.append( outputName( column ) ); 77 | buff.append(" SET DEFAULT "); 78 | buff.append(value); 79 | try 80 | { 81 | // System.out.println("C: " + buff); 82 | con.executeQuery(buff.toString()); 83 | } 84 | catch(SQLException ex) 85 | { 86 | if(ex.getMessage().contains("ultiple")) 87 | { 88 | throw ex; 89 | } 90 | } 91 | } 92 | 93 | public void setNotNull( DBConnection con, String table, String typeName, String column, Integer size ) 94 | throws Exception 95 | { 96 | StringBuilder buff = new StringBuilder("ALTER TABLE "); 97 | buff.append( table ); 98 | buff.append(" ALTER COLUMN "); 99 | buff.append(column); 100 | buff.append(" SET NOT NULL"); 101 | try 102 | { 103 | // System.out.println("C: " + buff); 104 | con.executeQuery(buff.toString()); 105 | } 106 | catch(SQLException ex) 107 | { 108 | if(ex.getMessage().contains("ultiple")) 109 | { 110 | System.out.println("EX: " + table + "-" + column + ": " + ex.getMessage()); 111 | // throw ex; 112 | } 113 | } 114 | } 115 | 116 | @Override 117 | public String normalizeValue( String value ) 118 | { 119 | return value; 120 | } 121 | 122 | @Override 123 | public String outputValue( String value ) 124 | { 125 | return value; 126 | } 127 | 128 | @Override 129 | public Object outputValue( Object value ) 130 | { 131 | return value; 132 | } 133 | 134 | @Override 135 | public int translateType(int type) 136 | { 137 | return type; 138 | } 139 | 140 | @Override 141 | public String normalizeDefault(String string) 142 | { 143 | return string; 144 | } 145 | 146 | @Override 147 | public String getParametersHelp() { 148 | return null; 149 | } 150 | 151 | @Override 152 | public void setPreparedValue(PreparedStatement pStm, int col, Object o, int type ) 153 | throws SQLException 154 | { 155 | if(type == Types.TIME) 156 | { 157 | o = new Timestamp(((Time) o).getTime()); 158 | type = Types.TIMESTAMP; 159 | } 160 | else if( ( type == Types.BOOLEAN || type == Types.BIT ) && o != null ) 161 | { 162 | o = "1".equals( "" + o ) || "true".equals( "" + o ) || "t".equals( "" + o )? "1": "0"; 163 | } 164 | if(o == null) 165 | { 166 | pStm.setNull(col + 1, translateType( type ) ); 167 | } 168 | else if( type == Types.BLOB || type == Types.LONGVARBINARY || type == Types.VARBINARY ) 169 | { 170 | o = outputValue( o ); 171 | System.out.println( "BLOB class: " + o.getClass() + " Type: " + type ); 172 | if( o instanceof byte[] ) 173 | { 174 | pStm.setBytes( col + 1, ( byte[] )o ); 175 | } 176 | else 177 | { 178 | pStm.setBlob( col + 1, ( Blob )o ); 179 | } 180 | } 181 | else 182 | { 183 | // System.out.println( "SPV: " + o + " t: " + type ); 184 | pStm.setObject(col + 1, outputValue( o ), translateType( type ) ); 185 | } 186 | } 187 | 188 | @Override 189 | public void setupStatement(Statement stm) 190 | throws SQLException 191 | { 192 | } 193 | 194 | public void initConnection( DBConnection con) throws Exception 195 | { 196 | } 197 | 198 | public boolean isTableValid(Name n) 199 | { 200 | return true; 201 | } 202 | 203 | @Override 204 | public String getDropTable(String table) { 205 | return "DROP TABLE " + table; 206 | } 207 | 208 | @Override 209 | public String getBegin() { 210 | return "BEGIN"; 211 | } 212 | 213 | @Override 214 | public String getCommit() { 215 | return "COMMIT"; 216 | } 217 | 218 | @Override 219 | public String getRollback() { 220 | return "ROLLBAK"; 221 | } 222 | 223 | @Override 224 | public String getCreateTablePrefix() { 225 | return ""; 226 | } 227 | 228 | @Override 229 | public String getType() { 230 | return null; 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/sql/Insert.java: -------------------------------------------------------------------------------- 1 | package pt.evolute.utils.sql; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.SQLException; 5 | 6 | import pt.evolute.utils.arrays.Virtual2DArray; 7 | import pt.evolute.utils.db.ExecuterProvider; 8 | import pt.evolute.utils.jdbc.StatementExecuterFactory; 9 | import pt.evolute.utils.sql.backend.Backend; 10 | import pt.evolute.utils.sql.backend.BackendProvider; 11 | 12 | public class Insert implements UpdateQuery 13 | { 14 | private static final int REGULAR = 0; 15 | private static final int SELECT = 1; 16 | 17 | private final String iTableName; 18 | private final Assignment []iAssignments; 19 | private final Field []iFields; 20 | private final Select iSelect; 21 | private final int iInsertType; 22 | private boolean unicodeFullStatement = false; 23 | // private AutoKeyRetriever autoKeyRetriever = null; 24 | 25 | private Virtual2DArray res; 26 | 27 | private final String iStatement; 28 | 29 | private int batchSize = -1; 30 | 31 | private Backend backend = null; 32 | 33 | public Insert( String insertQuery ) 34 | { 35 | iStatement = insertQuery; 36 | iTableName = null; 37 | iAssignments = null; 38 | iFields = null; 39 | iSelect = null; 40 | iInsertType = REGULAR; 41 | } 42 | 43 | public Insert( String tableName, Assignment []assignments ) 44 | { 45 | iStatement = null; 46 | iTableName = tableName; 47 | iAssignments = assignments; 48 | iInsertType = REGULAR; 49 | iSelect = null; 50 | iFields = null; 51 | } 52 | 53 | public Insert( String tableName, Field []fields, 54 | Select select ) 55 | { 56 | iStatement = null; 57 | iTableName = tableName; 58 | iAssignments = null; 59 | iFields = fields; 60 | iSelect = select; 61 | iInsertType = SELECT; 62 | } 63 | 64 | /* public void setKeyRetriever( AutoKeyRetriever keyRetriever ) 65 | { 66 | autoKeyRetriever = keyRetriever; 67 | } 68 | */ 69 | public void setUnicodeFullStatement( boolean translate ) 70 | { 71 | unicodeFullStatement = translate; 72 | } 73 | 74 | @Override 75 | public String toString() 76 | { 77 | if( iStatement != null ) 78 | { 79 | return toUnicode( iStatement ).toString(); 80 | } 81 | 82 | if( iTableName == null || iTableName.length() == 0 ) 83 | { 84 | return null; 85 | } 86 | StringBuilder insertStr = new StringBuilder( "INSERT INTO " ).append( iTableName ); 87 | 88 | switch( iInsertType ) 89 | { 90 | case REGULAR: 91 | toStringRegular( insertStr ); 92 | break; 93 | case SELECT: 94 | toStringSelect( insertStr ); 95 | break; 96 | default: 97 | return null; 98 | } 99 | return toUnicode( insertStr ).toString(); 100 | } 101 | 102 | private void toStringRegular( StringBuilder builder ) 103 | { 104 | if( iAssignments == null || iAssignments.length == 0 ) 105 | { 106 | builder.append( " DEFAULT VALUES;" ); 107 | } 108 | else 109 | { 110 | builder.append( "(" ); 111 | StringBuilder values = new StringBuilder( " ) VALUES ( " ); 112 | for( int n = 0; n < iAssignments.length; n++ ) 113 | { 114 | iAssignments[ n ].setBackend( backend ); 115 | // iAssignments[ n ].getOperand().setUnicode( unicode ); 116 | builder.append( iAssignments[ n ].getLeft() ); 117 | values.append( iAssignments[ n ].getRight() ); 118 | if( n < iAssignments.length - 1 ) 119 | { 120 | builder.append( ", " ); 121 | values.append( ", " ); 122 | } 123 | } 124 | builder.append( values ); 125 | builder.append( " );" ); 126 | } 127 | } 128 | 129 | private void toStringSelect( StringBuilder builder ) 130 | { 131 | String selectStr = iSelect.toString(); 132 | if( iFields == null || iFields.length == 0 || 133 | selectStr == null || selectStr.length() == 0 ) 134 | { 135 | builder.append( " DEFAULT VALUES;" ); 136 | } 137 | else 138 | { 139 | builder.append( "(" ); 140 | for( int n = 0; n < iFields.length; n++ ) 141 | { 142 | builder.append( iFields[ n ].toString() ); 143 | if( n < iFields.length - 1 ) 144 | { 145 | builder.append( ", " ); 146 | } 147 | } 148 | builder.append( " ) " ); 149 | builder.append( selectStr ); 150 | } 151 | } 152 | 153 | private CharSequence toUnicode( CharSequence str ) 154 | { 155 | if( unicodeFullStatement ) 156 | { 157 | return backend.escapeUnicode( str ); 158 | } 159 | else 160 | { 161 | return str; 162 | } 163 | } 164 | 165 | public void execute() 166 | throws Exception 167 | { 168 | res = StatementExecuterFactory.executeUpdateStatementWithCursor( this.toString(), this ); 169 | } 170 | 171 | public void execute( ExecuterProvider provider ) 172 | throws Exception 173 | { 174 | res = provider.getExecuter().executeQuery( this ); 175 | } 176 | 177 | public Object[][] getObjects() 178 | { 179 | return res.getObjects(); 180 | } 181 | 182 | public Virtual2DArray getCursorObjects() 183 | { 184 | return res; 185 | } 186 | 187 | /* public AutoKeyRetriever getKeyRetriever() 188 | { 189 | return autoKeyRetriever; 190 | } 191 | */ 192 | public String[] getBatch() 193 | { 194 | String inserts[] = new String[ batchSize ]; 195 | for( int i = 0; i < batchSize; ++i ) 196 | { 197 | for( int j = 0; j < iAssignments.length; ++j ) 198 | { 199 | if( iAssignments[ j ].isBatch() ) 200 | { 201 | iAssignments[ j ].currentBatch( i ); 202 | } 203 | } 204 | inserts[ i ] = toString(); 205 | } 206 | return inserts; 207 | } 208 | 209 | public boolean isBatch() 210 | { 211 | if( iAssignments != null ) 212 | { 213 | for( int i = 0; i < iAssignments.length; ++i ) 214 | { 215 | if( iAssignments[ i ].isBatch() ) 216 | { 217 | batchSize = iAssignments[ i ].getBatchSize(); 218 | return true; 219 | } 220 | } 221 | } 222 | return false; 223 | } 224 | 225 | public void fillParameters(Object stm) 226 | throws SQLException 227 | { 228 | int i = 1; 229 | PreparedStatement pstm = ( PreparedStatement )stm; 230 | if( iAssignments != null ) 231 | { 232 | for( Assignment a: iAssignments ) 233 | { 234 | a.getOperand().setBackend( getBackend() ); 235 | // a.getOperand().setUnicode( unicode ); 236 | if( a.getOperand().getInnerObject() instanceof byte[] ) 237 | { 238 | pstm.setBytes( i, ( byte[] )a.getOperand().getInnerObject() ); 239 | ++i; 240 | } 241 | } 242 | } 243 | } 244 | 245 | public void setBackend( Backend backend ) 246 | { 247 | this.backend = backend; 248 | } 249 | 250 | protected Backend getBackend() 251 | { 252 | if( backend == null ) 253 | { 254 | new Exception( "NO BACKEND!!!!" ).printStackTrace( System.out ); 255 | backend = BackendProvider.getDefaultBackend(); 256 | } 257 | return backend; 258 | } 259 | } -------------------------------------------------------------------------------- /src/main/java/pt/evolute/utils/string/EvoStringUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | 6 | package pt.evolute.utils.string; 7 | 8 | import java.util.Locale; 9 | 10 | /** 11 | * 12 | * @author lflores 13 | */ 14 | public class EvoStringUtils 15 | { 16 | 17 | public static String parsePlica( CharSequence str ) 18 | { 19 | String result = str.toString(); 20 | if ( result != null ) 21 | { 22 | result = result.replaceAll( "'", "\\\\'" ); 23 | } 24 | return result; 25 | } 26 | 27 | public static String parsePlica( CharSequence str, String plicaEscaped ) 28 | { 29 | String result = str.toString(); 30 | if ( result != null ) 31 | { 32 | result = result.replaceAll( "'", plicaEscaped ); 33 | } 34 | return result; 35 | } 36 | 37 | public static String trimChar( String str, char ch ) 38 | { 39 | return trimChar( str, ch, true, true ); 40 | } 41 | 42 | public static String trimChar( String str, char ch, boolean left, boolean right ) 43 | { 44 | String out = str; 45 | if( left ) 46 | { 47 | int i = 0; 48 | while( out.charAt( i ) == ch ) 49 | { 50 | ++i; 51 | } 52 | if( i > 0 ) 53 | { 54 | out = str.substring( i ); 55 | } 56 | } 57 | if( right ) 58 | { 59 | int i = out.length() - 1; 60 | while( out.charAt( i ) == ch ) 61 | { 62 | --i; 63 | } 64 | if( i < out.length() - 1 ) 65 | { 66 | out = out.substring( 0, i ); 67 | } 68 | } 69 | return out; 70 | } 71 | 72 | /** 73 | *removes the first occurrence of removeThis after afterThis (NOT case sensitive) 74 | * 75 | */ 76 | public static String removeAfter( String source, String removeThis, String afterThis ) 77 | { 78 | String ret = source; 79 | int pos = source.toLowerCase(Locale.ENGLISH).indexOf( afterThis.toLowerCase(Locale.ENGLISH) ); 80 | if( pos != -1 ) 81 | { 82 | pos = source.indexOf( removeThis, pos ); 83 | if( pos != -1 ) 84 | { 85 | ret= source.substring( 0, pos ) + source.substring( pos + removeThis.length(), source.length() ); 86 | } 87 | } 88 | return ret; 89 | } 90 | 91 | /** 92 | *removes the first occurrence of removeThis after afterThis (case sensitive) 93 | * 94 | */ 95 | public static String removeAfterSensitive( String source, String removeThis, String afterThis ) 96 | { 97 | String ret = source; 98 | int pos = source.indexOf( afterThis ); 99 | if( pos != -1 ) 100 | { 101 | pos = source.indexOf( removeThis, pos ); 102 | ret= source.substring( 0, pos ) + source.substring( pos + removeThis.length(), source.length() ); 103 | } 104 | return ret; 105 | } 106 | 107 | public static boolean isNum( String target ) 108 | { 109 | boolean ret = true; 110 | for( int i = 0 ; i < target.length(); i++ ) 111 | { 112 | char x = target.charAt( i ); 113 | if( x != '.' && x != ',' && ( x < '0' || x > '9' ) ) 114 | { 115 | ret = false; 116 | break; 117 | } 118 | } 119 | return ret; 120 | } 121 | 122 | 123 | 124 | 125 | private static int findFirstDigitBackwards( String str ) 126 | { 127 | int index = -1; 128 | if ( str != null ) 129 | { 130 | if ( Character.isDigit( str.charAt( str.length() - 1 ) ) ) 131 | { 132 | for ( int i = str.length() - 1; i >= 0; i-- ) 133 | { 134 | char charAtIndex = str.charAt( i ); 135 | if ( Character.isDigit( charAtIndex ) ) 136 | { 137 | // index = ( i == str.length() - 1 ) ? i : i + 1; 138 | index = i; 139 | } 140 | else 141 | { 142 | break; 143 | } 144 | } 145 | } 146 | } 147 | return index; 148 | } 149 | 150 | private static String incrementAsLong( String str ) 151 | { 152 | String result = null; 153 | if ( str != null ) 154 | { 155 | try 156 | { 157 | Long asInteger = Long.parseLong( str ); 158 | Long incremented = asInteger + 1; 159 | result = incremented.toString(); 160 | } 161 | catch ( Exception e ) 162 | { 163 | result = null; 164 | } 165 | } 166 | return result; 167 | } 168 | 169 | private static String increment( char[] str ) 170 | { 171 | for( int pos = str.length - 1; pos >= 0; pos-- ) 172 | { 173 | if ( Character.toUpperCase( str[ pos ] ) != 'Z' ) 174 | { 175 | if ( str[ pos ] == '9' ) 176 | { 177 | String word = new String( str ); 178 | String begin = word.substring( 0, pos + 1 ); 179 | String rest = word.substring( pos + 1, word.length() ); 180 | 181 | int index = findFirstDigitBackwards( begin ); 182 | String left = begin.substring( 0, index ); 183 | String number = begin.substring( index, begin.length() ); 184 | 185 | return left + incrementAsLong( number ) + rest; 186 | } 187 | else 188 | { 189 | str[ pos ]++; 190 | break; 191 | } 192 | } 193 | else 194 | { 195 | str[ pos ] = 'a'; 196 | } 197 | } 198 | return new String( str ); 199 | } 200 | 201 | private static boolean isAllZs( String str ) 202 | { 203 | boolean result = false; 204 | if ( str != null ) 205 | { 206 | StringBuilder builder = new StringBuilder( str.length() ); 207 | for ( int i = 0; i < str.length(); i++ ) 208 | { 209 | builder.append( "Z" ); 210 | } 211 | result = str.equals( builder.toString() ); 212 | } 213 | return result; 214 | } 215 | 216 | public static String increment( String str ) 217 | { 218 | String result = null; 219 | if ( str != null ) 220 | { 221 | // try integer 222 | result = incrementAsLong( str ); 223 | 224 | // try string + integer 225 | if ( result == null ) 226 | { 227 | int index = findFirstDigitBackwards( str ); 228 | if ( index > -1 ) 229 | { 230 | String left = str.substring( 0, index ); 231 | String right = str.substring( index, str.length() ); 232 | result = left + incrementAsLong( right ); 233 | } 234 | } 235 | 236 | // increment chars 237 | if ( result == null ) 238 | { 239 | result = increment( str.toCharArray() ); 240 | if ( isAllZs( str ) ) 241 | { 242 | result = "1" + result; 243 | } 244 | } 245 | } 246 | return result; 247 | } 248 | 249 | 250 | 251 | 252 | private static void test( String str ) 253 | { 254 | System.out.println( "Test case : " + str ); 255 | System.out.println( "\tString incremented : " + increment( str ) ); 256 | // System.out.println( " " ); 257 | } 258 | 259 | public static void main( String ... args ) 260 | { 261 | test( "9" ); 262 | test( "Z" ); 263 | test( "9Z" ); 264 | test( "10a" ); 265 | test( "Z9" ); 266 | test( "0Z" ); 267 | // System.out.println( "original : " + incrementOriginal( toIncrement.toCharArray() ) ); 268 | } 269 | 270 | } 271 | --------------------------------------------------------------------------------