diff --git a/.rultor.yml b/.rultor.yml index 0045b46..54df89d 100644 --- a/.rultor.yml +++ b/.rultor.yml @@ -3,15 +3,14 @@ env: assets: pgSecret.txt: rocket-3/dbgit-test#pgSecret.txt gitSecret.txt: rocket-3/dbgit-test#gitSecret.txt -merge: - script: |- +install: |- java -version --batch-mode mvn -version --batch-mode - mvn clean install package appassembler:assemble -D skipTests --batch-mode - mvn test -Dtest=*selfTest,*DbGitIntegrationTestBasic* --batch-mode + mvn clean install package appassembler:assemble -D skipTests --batch-mode --quiet + chmod u+r+x target/dbgit/bin/dbgit +merge: + script: |- + mvn test -Dtest=${tests:-'*selfTest,*DbGitIntegrationTestBasic*'} --batch-mode deploy: script: |- - java -version - mvn -version - mvn clean install package appassembler:assemble -D skipTests --batch-mode - mvn test -Dtest=*selfTest,*DbGitIntegrationTestBasic* --batch-mode + mvn test -Dtest=${tests:-'*selfTest,*DbGitIntegrationTestBasic*'} --batch-mode diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapter.java b/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapter.java index e128dee..ff75722 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapter.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapter.java @@ -169,6 +169,9 @@ private void printRestoreMessage(IMetaObject obj) { if(obj instanceof MetaView){ leafName = "restoreView"; } if(obj instanceof MetaTrigger){ leafName = "restoreTrigger"; } if(obj instanceof MetaSchema){ leafName = "restoreSchema"; } + if(obj instanceof MetaUDT){ leafName = "restoreUDT"; } + if(obj instanceof MetaEnum){ leafName = "restoreEnum"; } + if(obj instanceof MetaDomain){ leafName = "restoreDomain"; } if(obj instanceof MetaRole){ leafName = "restoreRole"; } if(obj instanceof MetaProcedure){ leafName = "restorePrc"; } if(obj instanceof MetaPackage){ leafName = "restorePkg"; } diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapterProxy.java b/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapterProxy.java index 6e0ecc6..8f7797d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapterProxy.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapterProxy.java @@ -8,6 +8,8 @@ import ru.fusionsoft.dbgit.core.SchemaSynonym; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.dbobjects.DBConstraint; +import ru.fusionsoft.dbgit.dbobjects.DBDomain; +import ru.fusionsoft.dbgit.dbobjects.DBEnum; import ru.fusionsoft.dbgit.dbobjects.DBFunction; import ru.fusionsoft.dbgit.dbobjects.DBIndex; import ru.fusionsoft.dbgit.dbobjects.DBPackage; @@ -22,6 +24,7 @@ import ru.fusionsoft.dbgit.dbobjects.DBTableSpace; import ru.fusionsoft.dbgit.dbobjects.DBTrigger; import ru.fusionsoft.dbgit.dbobjects.DBUser; +import ru.fusionsoft.dbgit.dbobjects.DBUserDefinedType; import ru.fusionsoft.dbgit.dbobjects.DBView; import ru.fusionsoft.dbgit.meta.IMapMetaObject; @@ -186,7 +189,37 @@ public Map getUsers() { public Map getRoles() { return adapter.getRoles(); } - + + @Override + public Map getUDTs(String schema) { + return adapter.getUDTs(schema); + } + + @Override + public Map getDomains(String schema) { + return adapter.getDomains(schema); + } + + @Override + public Map getEnums(String schema) { + return adapter.getEnums(schema); + } + + @Override + public DBUserDefinedType getUDT(String schema, String name) { + return adapter.getUDT(schema, name); + } + + @Override + public DBDomain getDomain(String schema, String name) { + return adapter.getDomain(schema, name); + } + + @Override + public DBEnum getEnum(String schema, String name) { + return adapter.getEnum(schema, name); + } + public T schemaSynonymMap(T object) { if (object == null) return null; diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/IDBAdapter.java b/src/main/java/ru/fusionsoft/dbgit/adapters/IDBAdapter.java index ecad994..0d366f6 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/IDBAdapter.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/IDBAdapter.java @@ -7,6 +7,8 @@ import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.dbobjects.DBConstraint; +import ru.fusionsoft.dbgit.dbobjects.DBDomain; +import ru.fusionsoft.dbgit.dbobjects.DBEnum; import ru.fusionsoft.dbgit.dbobjects.DBFunction; import ru.fusionsoft.dbgit.dbobjects.DBIndex; import ru.fusionsoft.dbgit.dbobjects.DBPackage; @@ -21,6 +23,7 @@ import ru.fusionsoft.dbgit.dbobjects.DBTableSpace; import ru.fusionsoft.dbgit.dbobjects.DBTrigger; import ru.fusionsoft.dbgit.dbobjects.DBUser; +import ru.fusionsoft.dbgit.dbobjects.DBUserDefinedType; import ru.fusionsoft.dbgit.dbobjects.DBView; import ru.fusionsoft.dbgit.meta.IMapMetaObject; @@ -143,7 +146,13 @@ public interface IDBAdapter { public Map getUsers(); public Map getRoles(); - + Map getUDTs(String schema); + Map getDomains(String schema); + Map getEnums(String schema); + DBUserDefinedType getUDT(String schema, String name); + DBDomain getDomain(String schema, String name); + DBEnum getEnum(String schema, String name); + public boolean userHasRightsToGetDdlOfOtherUsers(); public IFactoryDBBackupAdapter getBackupAdapterFactory(); diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdRestore.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdRestore.java index 513578e..07eb480 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdRestore.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdRestore.java @@ -210,8 +210,9 @@ private boolean checkNeedsRestore(IMetaObject obj){ final boolean exists = GitMetaDataManager.getInstance().loadFromDB(dbObj); isRestore = !exists || !dbObj.getHash().equals(obj.getHash()); } catch (ExceptionDBGit e) { - isRestore = true; - e.printStackTrace(); + throw new ExceptionDBGitRunTime(e); +// isRestore = true; +// e.printStackTrace(); } return isRestore; } diff --git a/src/main/java/ru/fusionsoft/dbgit/core/DBGitIndex.java b/src/main/java/ru/fusionsoft/dbgit/core/DBGitIndex.java index cbabb81..735eff8 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/DBGitIndex.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/DBGitIndex.java @@ -77,8 +77,7 @@ public boolean removeItem(String name) { saveDBIndex(); return true; } catch (Exception ex){ - ex.printStackTrace(); - return false; + throw new ExceptionDBGitRunTime("Remove item from index error", ex); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/core/GitMetaDataManager.java b/src/main/java/ru/fusionsoft/dbgit/core/GitMetaDataManager.java index a95d943..bf50d04 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/GitMetaDataManager.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/GitMetaDataManager.java @@ -94,7 +94,7 @@ private void addToMapSqlObject( objs.put(obj); } - } + } public boolean loadFromDB(IMetaObject obj) throws ExceptionDBGit { try { @@ -241,6 +241,12 @@ public IMapMetaObject loadDBMetaData(boolean includeBackupSchemas) throws Except addToMapSqlObject(dbObjs, adapter.getProcedures(schema.getName()), DBGitMetaType.DbGitProcedure); if (!ignore.matchOne(schema.getName() + "/*." + DBGitMetaType.DbGitView.getValue())) addToMapSqlObject(dbObjs, adapter.getViews(schema.getName()), DBGitMetaType.DbGitView); + if (!ignore.matchOne(schema.getName() + "/*." + DBGitMetaType.DBGitEnum.getValue())) + addToMapSqlObject(dbObjs, adapter.getEnums(schema.getName()), DBGitMetaType.DBGitEnum); + if (!ignore.matchOne(schema.getName() + "/*." + DBGitMetaType.DBGitUserDefinedType.getValue())) + addToMapSqlObject(dbObjs, adapter.getUDTs(schema.getName()), DBGitMetaType.DBGitUserDefinedType); + if (!ignore.matchOne(schema.getName() + "/*." + DBGitMetaType.DBGitDomain.getValue())) + addToMapSqlObject(dbObjs, adapter.getDomains(schema.getName()), DBGitMetaType.DBGitDomain); } //data tables diff --git a/src/main/java/ru/fusionsoft/dbgit/data_table/RowData.java b/src/main/java/ru/fusionsoft/dbgit/data_table/RowData.java index abf313e..a3e58f7 100644 --- a/src/main/java/ru/fusionsoft/dbgit/data_table/RowData.java +++ b/src/main/java/ru/fusionsoft/dbgit/data_table/RowData.java @@ -1,190 +1,194 @@ -package ru.fusionsoft.dbgit.data_table; - -import java.io.IOException; -import java.sql.ResultSet; -import java.util.*; - -import de.siegmar.fastcsv.reader.CsvRow; -import org.apache.commons.csv.CSVPrinter; -import org.apache.commons.csv.CSVRecord; - -import ru.fusionsoft.dbgit.core.DBGitLang; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; -import ru.fusionsoft.dbgit.dbobjects.DBTable; -import ru.fusionsoft.dbgit.meta.MetaTable; -import ru.fusionsoft.dbgit.utils.CalcHash; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class RowData { - //protected Map data = new LinkedHashMap<>(); - private List rowList = new ArrayList<>(); - private String hashRow; - //protected String key; - //protected MetaTable metaTable; - - public RowData(ResultSet rs, MetaTable metaTable) throws Exception { - //this.metaTable = metaTable; - loadDataFromRS(rs, metaTable); - } - - public RowData(CsvRow record, MetaTable metaTable, CsvRow titleColumns) throws Exception { - //this.metaTable = metaTable; - loadDataFromCSVRecord(record, titleColumns, metaTable); - } - - public RowData(CSVRecord record, MetaTable metaTable, CSVRecord titleColumns) throws Exception { - //this.metaTable = metaTable; - loadDataFromCSVRecord(record, titleColumns, metaTable); - } - - public void loadDataFromRS(ResultSet rs, MetaTable metaTable) throws Exception { - for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) { - String columnName = rs.getMetaData().getColumnName(i+1); - - if (columnName.equalsIgnoreCase("DBGIT_ROW_NUM")) - continue; - - ICellData cd = FactoryCellData.createCellData(metaTable.getFieldsMap().get(columnName).getTypeUniversal()); - - if (cd.loadFromDB(rs, rs.getMetaData().getColumnName(i+1))) - rowList.add(cd); - //data.put(columnName, cd); - } - - hashRow = calcRowHash().substring(0, 24); - - //key = calcRowKey(metaTable.getIdColumns()); - } - - private void loadDataFromCSVRecord(CsvRow record, CsvRow titleColumns, MetaTable metaTable) throws Exception { - if (record.getFieldCount() != titleColumns.getFieldCount()) { - throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "dataTable", "differentCount")); - } - - for (int i = 0; i < record.getFieldCount(); i++) { - String columnName = titleColumns.getField(i); - if (metaTable.getFieldsMap().get(columnName) == null) { - throw new ExceptionDBGitRunTime(DBGitLang.getInstance().getValue("errors", "dataTable", "fieldNotFound").withParams(columnName)); - } - - ICellData cd = FactoryCellData.createCellData(metaTable.getFieldsMap().get(columnName).getTypeUniversal()); - cd.deserialize(record.getField(i).equals("") ? null : record.getField(i)); - - rowList.add(cd); - //data.put(columnName, cd); - } - hashRow = calcRowHash().substring(0, 24); - - //key = calcRowKey(metaTable.getIdColumns()); - - } - - private void loadDataFromCSVRecord(CSVRecord record, CSVRecord titleColumns, MetaTable metaTable) throws Exception { - - if (record.size() != titleColumns.size()) { - throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "dataTable", "differentCount")); - } - - for (int i = 0; i < record.size(); i++) { - String columnName = titleColumns.get(i); - if (metaTable.getFieldsMap().get(columnName) == null) { - throw new ExceptionDBGitRunTime(DBGitLang.getInstance().getValue("errors", "dataTable", "fieldNotFound").withParams(columnName)); - } - - ICellData cd = FactoryCellData.createCellData(metaTable.getFieldsMap().get(columnName).getTypeUniversal()); - cd.deserialize(record.get(i)); - - rowList.add(cd); - //data.put(columnName, cd); - } - hashRow = calcRowHash().substring(0, 24); - - //key = calcRowKey(metaTable.getIdColumns()); - } - - public void saveDataToCsv(CSVPrinter csvPrinter, DBTable tbl) throws Exception { - //for (ICellData cd : getData().values()) - for (ICellData cd : rowList) - csvPrinter.print(cd.serialize(tbl)); - - csvPrinter.println(); - } - /* - public String calcRowKey(List idColumns) throws Exception { - if (idColumns.size() > 0) { - StringBuilder keyBuilder = new StringBuilder(); - for (String nmId : idColumns) { - keyBuilder.append(data.get(nmId).convertToString()+"_"); - } - return keyBuilder.toString(); - } else { - return hashRow; - } - } - */ - public String calcRowKey(List idColumns) throws Exception { - return hashRow; - /* - if (idColumns.size() > 0) { - StringBuilder keyBuilder = new StringBuilder(); - for (Integer nmId : idColumns) { - keyBuilder.append(rowList.get(nmId).convertToString()+"_"); - } - return keyBuilder.toString(); - } else { - return hashRow; - }*/ - } - - - public String calcRowHash() throws Exception { - CalcHash ch = new CalcHash(); - //for (ICellData cd : data.values()) { - for (ICellData cd : rowList) { - String str = cd.convertToString(); - if ( str != null) - ch.addData(str); - } - return ch.calcHashStr(); - } - - public Map getData(List fields) { - Map res = new LinkedHashMap<>(); - - int i = 0; - for (ICellData cd : rowList) { - res.put(fields.get(i), cd); - i++; - } - - return res; - } - - public Map getData() { - Map res = new HashMap<>(); - - int i = 0; - for (ICellData cd : rowList) { - res.put(String.valueOf(i), cd); - i++; - } - - return res; - } - - public List getListData() { - return rowList; - } - - public String getHashRow() { - return hashRow; - } - - public String getKey() { - //return key; - return hashRow; - } - - -} +package ru.fusionsoft.dbgit.data_table; + +import java.sql.ResultSet; +import java.text.MessageFormat; +import java.util.*; + +import de.siegmar.fastcsv.reader.CsvRow; +import java.util.stream.Collectors; + +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.csv.CSVRecord; + +import ru.fusionsoft.dbgit.core.DBGitLang; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; +import ru.fusionsoft.dbgit.dbobjects.DBTable; +import ru.fusionsoft.dbgit.meta.MetaTable; +import ru.fusionsoft.dbgit.utils.CalcHash; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class RowData { + //protected Map data = new LinkedHashMap<>(); + private List rowList = new ArrayList<>(); + private String hashRow; + //protected String key; + //protected MetaTable metaTable; + + public RowData(ResultSet rs, MetaTable metaTable) throws Exception { + //this.metaTable = metaTable; + loadDataFromRS(rs, metaTable); + } + + public RowData(CsvRow record, MetaTable metaTable, CsvRow titleColumns) throws Exception { + //this.metaTable = metaTable; + loadDataFromCSVRecord(record, titleColumns, metaTable); + } + + @Deprecated + public RowData(CSVRecord record, MetaTable metaTable, CSVRecord titleColumns) throws Exception { + //this.metaTable = metaTable; + loadDataFromCSVRecord(record, titleColumns, metaTable); + } + + private void loadDataFromRS(ResultSet rs, MetaTable metaTable) throws Exception { + for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) { + String columnName = rs.getMetaData().getColumnName(i+1); + + if (columnName.equalsIgnoreCase("DBGIT_ROW_NUM")) + continue; + + ICellData cd = FactoryCellData.createCellData(metaTable.getFieldsMap().get(columnName).getTypeUniversal()); + + if (cd.loadFromDB(rs, rs.getMetaData().getColumnName(i+1))) + rowList.add(cd); + //data.put(columnName, cd); + } + + hashRow = calcRowHash().substring(0, 24); + + //key = calcRowKey(metaTable.getIdColumns()); + } + + private void loadDataFromCSVRecord(CsvRow record, CsvRow titleColumns, MetaTable metaTable) throws Exception { + if (record.getFieldCount() != titleColumns.getFieldCount()) { + throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "dataTable", "differentCount")); + } + + for (int i = 0; i < record.getFieldCount(); i++) { + String columnName = titleColumns.getField(i); + if (metaTable.getFieldsMap().get(columnName) == null) { + throw new ExceptionDBGitRunTime(DBGitLang.getInstance().getValue("errors", "dataTable", "fieldNotFound").withParams(columnName)); + } + + ICellData cd = FactoryCellData.createCellData(metaTable.getFieldsMap().get(columnName).getTypeUniversal()); + cd.deserialize(record.getField(i).equals("") ? null : record.getField(i)); + + rowList.add(cd); + //data.put(columnName, cd); + } + hashRow = calcRowHash().substring(0, 24); + + //key = calcRowKey(metaTable.getIdColumns()); + + } + + @Deprecated + private void loadDataFromCSVRecord(CSVRecord record, CSVRecord titleColumns, MetaTable metaTable) throws Exception { + + if (record.size() != titleColumns.size()) { + throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "dataTable", "differentCount")); + } + + for (int i = 0; i < record.size(); i++) { + String columnName = titleColumns.get(i); + if (metaTable.getFieldsMap().get(columnName) == null) { + throw new ExceptionDBGitRunTime(DBGitLang.getInstance().getValue("errors", "dataTable", "fieldNotFound").withParams(columnName)); + } + + ICellData cd = FactoryCellData.createCellData(metaTable.getFieldsMap().get(columnName).getTypeUniversal()); + cd.deserialize(record.get(i)); + + rowList.add(cd); + //data.put(columnName, cd); + } + hashRow = calcRowHash().substring(0, 24); + + //key = calcRowKey(metaTable.getIdColumns()); + } + + public void saveDataToCsv(CSVPrinter csvPrinter, DBTable tbl) throws Exception { + //for (ICellData cd : getData().values()) + for (ICellData cd : rowList) + csvPrinter.print(cd.serialize(tbl)); + + csvPrinter.println(); + } + /* + public String calcRowKey(List idColumns) throws Exception { + if (idColumns.size() > 0) { + StringBuilder keyBuilder = new StringBuilder(); + for (String nmId : idColumns) { + keyBuilder.append(data.get(nmId).convertToString()+"_"); + } + return keyBuilder.toString(); + } else { + return hashRow; + } + } + */ + public String calcRowKey(List idColumns) throws Exception { + return hashRow; + /* + if (idColumns.size() > 0) { + StringBuilder keyBuilder = new StringBuilder(); + for (Integer nmId : idColumns) { + keyBuilder.append(rowList.get(nmId).convertToString()+"_"); + } + return keyBuilder.toString(); + } else { + return hashRow; + }*/ + } + + + public String calcRowHash() throws Exception { + CalcHash ch = new CalcHash(); + //for (ICellData cd : data.values()) { + for (ICellData cd : rowList) { + String str = cd.convertToString(); + if ( str != null) + ch.addData(str); + } + return ch.calcHashStr(); + } + + public Map getData(List fields) { + Map res = new LinkedHashMap<>(); + + int i = 0; + for (ICellData cd : rowList) { + res.put(fields.get(i), cd); + i++; + } + + return res; + } + + public Map getData() { + Map res = new HashMap<>(); + + int i = 0; + for (ICellData cd : rowList) { + res.put(String.valueOf(i), cd); + i++; + } + + return res; + } + + public List getListData() { + return rowList; + } + + public String getHashRow() { + return hashRow; + } + + public String getKey() { + //return key; + return hashRow; + } + + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBDomain.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBDomain.java new file mode 100644 index 0000000..92c437d --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBDomain.java @@ -0,0 +1,13 @@ +package ru.fusionsoft.dbgit.dbobjects; + +import java.util.Set; +import ru.fusionsoft.dbgit.utils.StringProperties; + +public class DBDomain extends DBSQLObject { + public DBDomain() { + } + + public DBDomain(String name, StringProperties options, String schema, String owner, Set dependencies, String sql) { + super(name, options, schema, owner, dependencies, sql); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBEnum.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBEnum.java new file mode 100644 index 0000000..dae9f76 --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBEnum.java @@ -0,0 +1,13 @@ +package ru.fusionsoft.dbgit.dbobjects; + +import java.util.Set; +import ru.fusionsoft.dbgit.utils.StringProperties; + +public class DBEnum extends DBSQLObject { + public DBEnum() { + } + + public DBEnum(String name, StringProperties options, String schema, String owner, Set dependencies, String sql) { + super(name, options, schema, owner, dependencies, sql); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBUserDefinedType.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBUserDefinedType.java new file mode 100644 index 0000000..cf064a9 --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBUserDefinedType.java @@ -0,0 +1,13 @@ +package ru.fusionsoft.dbgit.dbobjects; + +import java.util.Set; +import ru.fusionsoft.dbgit.utils.StringProperties; + +public class DBUserDefinedType extends DBSQLObject { + public DBUserDefinedType() { + } + + public DBUserDefinedType(String name, StringProperties options, String schema, String owner, Set dependencies, String sql) { + super(name, options, schema, owner, dependencies, sql); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/DBGitMetaType.java b/src/main/java/ru/fusionsoft/dbgit/meta/DBGitMetaType.java index 73b678c..78452b6 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/DBGitMetaType.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/DBGitMetaType.java @@ -46,6 +46,36 @@ public Integer getPriority() { } }, + DBGitUserDefinedType("udt"){ + public Class getMetaClass() { + return MetaUDT.class; + } + + public Integer getPriority() { + return 11; + } + }, + + DBGitEnum("enum"){ + public Class getMetaClass() { + return MetaEnum.class; + } + + public Integer getPriority() { + return 12; + } + }, + + DBGitDomain("domain"){ + public Class getMetaClass() { + return MetaDomain.class; + } + + public Integer getPriority() { + return 13; + } + }, + DBGitSequence("seq"){ public Class getMetaClass() { return MetaSequence.class; @@ -134,8 +164,7 @@ public Class getMetaClass() { public Integer getPriority() { return 210; } - } - ; + }; private static Map listAllTypes; static { diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaDomain.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaDomain.java new file mode 100644 index 0000000..a7aa969 --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaDomain.java @@ -0,0 +1,40 @@ +package ru.fusionsoft.dbgit.meta; + +import ru.fusionsoft.dbgit.adapters.AdapterFactory; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.dbobjects.DBDomain; +import ru.fusionsoft.dbgit.dbobjects.DBSQLObject; + +public class MetaDomain extends MetaSql { + public MetaDomain() { + } + + public MetaDomain(DBSQLObject sqlObject) throws ExceptionDBGit { + super(sqlObject); + } + + /** + * @return Type meta object + */ + @Override + public final IDBGitMetaType getType() { + return DBGitMetaType.DBGitDomain; + } + + /** + * load current object from DB + */ + @Override + public final boolean loadFromDB() throws ExceptionDBGit { + final IDBAdapter adapter = AdapterFactory.createAdapter(); + final NameMeta nm = MetaObjectFactory.parseMetaName(name); + final DBDomain dbObject = adapter.getDomain(nm.getSchema(), nm.getName()); + + if (dbObject != null) { + setSqlObject(dbObject); + return true; + } else + return false; + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaEnum.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaEnum.java new file mode 100644 index 0000000..fd41f51 --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaEnum.java @@ -0,0 +1,32 @@ +package ru.fusionsoft.dbgit.meta; + +import ru.fusionsoft.dbgit.adapters.AdapterFactory; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.dbobjects.DBEnum; + +public class MetaEnum extends MetaSql { + /** + * @return Type meta object + */ + @Override + public IDBGitMetaType getType() { + return DBGitMetaType.DBGitEnum; + } + + /** + * load current object from DB + */ + @Override + public boolean loadFromDB() throws ExceptionDBGit { + final IDBAdapter adapter = AdapterFactory.createAdapter(); + final NameMeta nm = MetaObjectFactory.parseMetaName(name); + final DBEnum dbObject = adapter.getEnum(nm.getSchema(), nm.getName()); + + if (dbObject != null) { + setSqlObject(dbObject); + return true; + } else + return false; + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaTableData.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaTableData.java index f547312..fa3042d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaTableData.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaTableData.java @@ -88,8 +88,10 @@ public void setTable(DBTable table) throws ExceptionDBGit { this.table = table; setName(table.getSchema()+"/"+table.getName()+"."+getType().getValue()); } - - + + public void setFields(List fields) { + this.fields = fields; + } @Override public void setName(String name) throws ExceptionDBGit { diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaUDT.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaUDT.java new file mode 100644 index 0000000..014fd0d --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaUDT.java @@ -0,0 +1,40 @@ +package ru.fusionsoft.dbgit.meta; + +import ru.fusionsoft.dbgit.adapters.AdapterFactory; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.dbobjects.DBSQLObject; +import ru.fusionsoft.dbgit.dbobjects.DBUserDefinedType; + +public class MetaUDT extends MetaSql { + public MetaUDT() { + } + + public MetaUDT(DBSQLObject sqlObject) throws ExceptionDBGit { + super(sqlObject); + } + + /** + * @return Type meta object + */ + @Override + public final IDBGitMetaType getType() { + return DBGitMetaType.DBGitUserDefinedType; + } + + /** + * load current object from DB + */ + @Override + public final boolean loadFromDB() throws ExceptionDBGit { + final IDBAdapter adapter = AdapterFactory.createAdapter(); + final NameMeta nm = MetaObjectFactory.parseMetaName(name); + final DBUserDefinedType dbObject = adapter.getUDT(nm.getSchema(), nm.getName()); + + if (dbObject != null) { + setSqlObject(dbObject); + return true; + } else + return false; + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssql.java index 5a32860..f33d99d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssql.java @@ -1163,6 +1163,39 @@ public Map getRoles() { return listRole; } + @Override + public Map getUDTs(String schema) { + return Collections.emptyMap(); + } + + @Override + public Map getDomains(String schema) { + return Collections.emptyMap(); + } + + @Override + public Map getEnums(String schema) { + return Collections.emptyMap(); + } + + @Override + public DBUserDefinedType getUDT(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + @Override + public DBDomain getDomain(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + @Override + public DBEnum getEnum(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + @Override public boolean userHasRightsToGetDdlOfOtherUsers() { try{ diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/DBAdapterMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/DBAdapterMySql.java index 774fe87..563da91 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/DBAdapterMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/DBAdapterMySql.java @@ -24,6 +24,8 @@ import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.core.db.FieldType; import ru.fusionsoft.dbgit.dbobjects.DBConstraint; +import ru.fusionsoft.dbgit.dbobjects.DBDomain; +import ru.fusionsoft.dbgit.dbobjects.DBEnum; import ru.fusionsoft.dbgit.dbobjects.DBFunction; import ru.fusionsoft.dbgit.dbobjects.DBIndex; import ru.fusionsoft.dbgit.dbobjects.DBPackage; @@ -37,6 +39,7 @@ import ru.fusionsoft.dbgit.dbobjects.DBTableSpace; import ru.fusionsoft.dbgit.dbobjects.DBTrigger; import ru.fusionsoft.dbgit.dbobjects.DBUser; +import ru.fusionsoft.dbgit.dbobjects.DBUserDefinedType; import ru.fusionsoft.dbgit.dbobjects.DBView; import ru.fusionsoft.dbgit.meta.IMapMetaObject; import ru.fusionsoft.dbgit.meta.TreeMapMetaObject; @@ -821,6 +824,39 @@ public Map getUsers() { @Override public Map getRoles() { return Collections.emptyMap(); } + @Override + public Map getUDTs(String schema) { + return Collections.emptyMap(); + } + + @Override + public Map getDomains(String schema) { + return Collections.emptyMap(); + } + + @Override + public Map getEnums(String schema) { + return Collections.emptyMap(); + } + + @Override + public DBUserDefinedType getUDT(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + @Override + public DBDomain getDomain(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + @Override + public DBEnum getEnum(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + protected String getFieldType(ResultSet rs) { try { final StringBuilder type = new StringBuilder(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBAdapterOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBAdapterOracle.java index c813cf5..032af9a 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBAdapterOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBAdapterOracle.java @@ -27,6 +27,8 @@ import ru.fusionsoft.dbgit.data_table.StringData; import ru.fusionsoft.dbgit.data_table.TextFileData; import ru.fusionsoft.dbgit.dbobjects.DBConstraint; +import ru.fusionsoft.dbgit.dbobjects.DBDomain; +import ru.fusionsoft.dbgit.dbobjects.DBEnum; import ru.fusionsoft.dbgit.dbobjects.DBFunction; import ru.fusionsoft.dbgit.dbobjects.DBIndex; import ru.fusionsoft.dbgit.dbobjects.DBPackage; @@ -41,6 +43,7 @@ import ru.fusionsoft.dbgit.dbobjects.DBTableSpace; import ru.fusionsoft.dbgit.dbobjects.DBTrigger; import ru.fusionsoft.dbgit.dbobjects.DBUser; +import ru.fusionsoft.dbgit.dbobjects.DBUserDefinedType; import ru.fusionsoft.dbgit.dbobjects.DBView; import ru.fusionsoft.dbgit.meta.IMapMetaObject; import ru.fusionsoft.dbgit.meta.IMetaObject; @@ -958,7 +961,39 @@ public Map getRoles() { return listRole; } - + @Override + public Map getUDTs(String schema) { + return Collections.emptyMap(); + } + + @Override + public Map getDomains(String schema) { + return Collections.emptyMap(); + } + + @Override + public Map getEnums(String schema) { + return Collections.emptyMap(); + } + + @Override + public DBUserDefinedType getUDT(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + @Override + public DBDomain getDomain(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + @Override + public DBEnum getEnum(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + static { reservedWords.add("ACCESS"); reservedWords.add("ADD"); diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBAdapterPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBAdapterPostgres.java index 21d5e12..14b7f95 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBAdapterPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBAdapterPostgres.java @@ -9,6 +9,7 @@ import com.diogonunes.jcdp.color.api.Ansi; import com.google.common.collect.ImmutableMap; +import java.util.stream.Collectors; import org.apache.commons.lang3.exception.ExceptionUtils; import ru.fusionsoft.dbgit.adapters.*; import ru.fusionsoft.dbgit.core.*; @@ -1010,6 +1011,220 @@ public Map getRoles() { return listRole; } + @Override + public Map getUDTs(String schema) { + final Map objects = new HashMap<>(); + final String query = + "SELECT \n" + + " n.nspname AS schema,\n" + + " t.typname AS name, \n" + + " r.rolname AS owner,\n" + + " pg_catalog.obj_description ( t.oid, 'pg_type' ) AS description\n" + + "FROM pg_type t \n" + + "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace \n" + + "LEFT JOIN pg_roles r ON r.oid = t.typowner\n" + + "WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) \n" + + "AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n" + + "AND t.typtype = 'c'\n" + + "AND n.nspname = '"+schema+"'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + while (rs.next()) { + final String name = rs.getString("name"); + final String owner = rs.getString("owner"); + final List attributesSqls = new ArrayList<>(); + final String attributesQuery = + "SELECT \n" + + " attribute_name AS \"name\", \n" + + " data_type AS \"type\", \n" + + " ordinal_position AS \"order\"\n" + + "FROM information_schema.attributes a\n" + + "WHERE udt_schema = '"+schema+"' AND udt_name = '"+name+"'\n" + + "ORDER BY ordinal_position"; + try (Statement stmt2 = getConnection().createStatement(); ResultSet attributeRs = stmt2.executeQuery( + attributesQuery)) { + while (attributeRs.next()) { + final String attrName = attributeRs.getString("name"); + final String attrType = attributeRs.getString("type"); + final String udtAttrDefinition = MessageFormat.format( + "{0} {1}", + escapeNameIfNeeded(attrName), + attrType + ); + attributesSqls.add(udtAttrDefinition); + } + } + final StringProperties options = new StringProperties(); + final String sql = MessageFormat.format( + "CREATE TYPE {0}.{1} AS (\n{2}\n);\n" + + "ALTER TYPE {0}.{1} OWNER TO {3};", + escapeNameIfNeeded(schema), + escapeNameIfNeeded(name), + String.join(",\n ", attributesSqls), + owner + ); + + DBUserDefinedType object = new DBUserDefinedType(name, options, schema, owner, Collections.emptySet(), sql); + options.addChild("attributes", String.join(",", attributesSqls)); + options.addChild("description", rs.getString("description")); + objects.put(name, object); + } + + } catch (Exception e) { + throw new ExceptionDBGitRunTime(e); + } + + return objects; + } + + @Override + public Map getDomains(String schema) { + System.out.println("getting domains"); + final Map objects = new HashMap<>(); + final String query = + "SELECT \n" + + " n.nspname,\n" + + " t.typname, \n" + + " dom.data_type, \n" + + " dom.domain_default,\n" + + " r.rolname,\n" + + " pg_catalog.obj_description ( t.oid, 'pg_type' ) AS description\n" + + "FROM pg_type t \n" + + "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace \n" + + "RIGHT JOIN information_schema.domains dom ON dom.domain_name = t.typname AND dom.domain_schema = n.nspname\n" + + "LEFT JOIN pg_roles r ON r.oid = t.typowner\n" + + "WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) \n" + + "AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n" + + "AND n.nspname NOT IN ('pg_catalog', 'information_schema')\n" + + "AND dom.domain_schema = '"+schema+"'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + + while (rs.next()) { + final String name = rs.getString("typname"); + final String owner = rs.getString("rolname"); + final String type = rs.getString("data_type"); + final String defaultValue = rs.getString("domain_default"); + + final List constraintSqls = new ArrayList<>(); + final String constraintsQuery = + "SELECT con.conname, con.convalidated, con.consrc\n" + + "FROM information_schema.domains dom\n" + + "INNER JOIN information_schema.domain_constraints dcon ON dcon.domain_schema = dom.domain_schema AND dcon.domain_name = dom.domain_name\n" + + "INNER JOIN pg_catalog.pg_constraint con ON dcon.constraint_name = con.conname\n" + + "WHERE dom.domain_schema = '"+schema+"' AND dom.domain_name = '"+name+"'"; + try (Statement stmt2 = getConnection().createStatement(); ResultSet conRs = stmt2.executeQuery(constraintsQuery)) { + while (conRs.next()) { + final String conName = conRs.getString("conname"); + final String conSrc = conRs.getString("consrc"); + final Boolean conIsValidated = conRs.getBoolean("convalidated"); + constraintSqls.add(MessageFormat.format( + "ALTER DOMAIN {0}.{1} ADD CONSTRAINT {2} CHECK {3} {4};", + escapeNameIfNeeded(schema), + escapeNameIfNeeded(name), + escapeNameIfNeeded(conName), + conSrc, + conIsValidated ? "" : "NOT VALID" + )); + } + } + + final StringProperties options = new StringProperties(rs); + final String sql = MessageFormat.format( + "CREATE DOMAIN {0}.{1} AS {2} {3}; ALTER DOMAIN {0}.{1} OWNER TO {4};\n{5}", + escapeNameIfNeeded(schema), escapeNameIfNeeded(name), type, defaultValue != null ? "DEFAULT " + defaultValue : "", owner, + String.join("\n", constraintSqls) + ); + + DBDomain object = new DBDomain(name, options, schema, owner, Collections.emptySet(), sql); + objects.put(name, object); + } + + } catch (Exception e) { + throw new ExceptionDBGitRunTime(e); + } + + return objects; + } + + @Override + public Map getEnums(String schema) { + System.out.println("getting enums"); + final Map objects = new HashMap<>(); + final String query = + "SELECT t.typname, r.rolname, pg_catalog.obj_description ( t.oid, 'pg_type' ) AS description," + + "ARRAY( \n" + + " SELECT e.enumlabel\n" + + " FROM pg_catalog.pg_enum e\n" + + " WHERE e.enumtypid = t.oid\n" + + " ORDER BY e.oid \n" + + ") AS elements\n" + + "FROM pg_type t \n" + + "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace \n" + + "LEFT JOIN pg_roles r ON r.oid = t.typowner\n" + + "WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) \n" + + "AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n" + + "AND n.nspname NOT IN ('pg_catalog', 'information_schema')\n" + + "AND n.nspname = '"+schema+"'" + + "AND t.typtype = 'e'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + + while (rs.next()) { + final String name = rs.getString("typname"); + final String owner = rs.getString("rolname"); + final String elements = String.join( + ",", + Arrays.stream((String[]) rs.getArray("elements").getArray()).map( x->"'"+x+"'").collect(Collectors.toList()) + ); + final StringProperties options = new StringProperties(); + final String sql = MessageFormat.format( + "CREATE TYPE {0}.{1} AS ENUM ({2});\nALTER TYPE {0}.{1} OWNER TO {3}", + schema, name, elements, owner + ); + + DBEnum object = new DBEnum(name, options, schema, owner, Collections.emptySet(), sql); + options.addChild("elements", elements); + objects.put(name, object); + } + + } catch (Exception e) { + throw new ExceptionDBGitRunTime(e); + } + + return objects; + } + + @Override + public DBUserDefinedType getUDT(String schema, String name) { + final Map udTs = getUDTs(schema); + if (udTs.containsKey(name)) { + return udTs.get(name); + } else { + throw new ExceptionDBGitObjectNotFound(lang.getValue("errors", "adapter", "objectNotFoundInDb").toString()); + } + } + + @Override + public DBDomain getDomain(String schema, String name) { + final Map domains = getDomains(schema); + if (domains.containsKey(name)) { + return domains.get(name); + } else { + throw new ExceptionDBGitObjectNotFound(lang.getValue("errors", "adapter", "objectNotFoundInDb").toString()); + } + } + + @Override + public DBEnum getEnum(String schema, String name) { + final Map enums = getEnums(schema); + if (enums.containsKey(name)) { + return enums.get(name); + } else { + throw new ExceptionDBGitObjectNotFound(lang.getValue("errors", "adapter", "objectNotFoundInDb").toString()); + } + } + @Override public boolean userHasRightsToGetDdlOfOtherUsers() { return true; } @Override diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreDomainPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreDomainPostgres.java new file mode 100644 index 0000000..56039a1 --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreDomainPostgres.java @@ -0,0 +1,122 @@ +package ru.fusionsoft.dbgit.postgres; + +import java.sql.Connection; +import java.text.MessageFormat; +import java.util.Map; +import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.DBGitConfig; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; +import ru.fusionsoft.dbgit.dbobjects.DBDomain; +import ru.fusionsoft.dbgit.dbobjects.DBSQLObject; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaDomain; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class DBRestoreDomainPostgres extends DBRestoreAdapter { + @Override + public final boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + final IDBAdapter adapter = getAdapter(); + final Connection connect = adapter.getConnection(); + try (final StatementLogging st = new StatementLogging( + connect, + adapter.getStreamOutputSqlCommand(), + adapter.isExecSql() + )) { + if (! ( obj instanceof MetaDomain )) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName(), + "domain", + obj.getType().getValue() + ) + ); + } + final DBSQLObject restoreDomain = (DBSQLObject) obj.getUnderlyingDbObject(); + final Map domains = adapter.getDomains(restoreDomain.getSchema()); + + if (domains.containsKey(restoreDomain.getName())) { + final DBDomain currentDomain = domains.get(restoreDomain.getName()); + if ( + ! restoreDomain.getOptions().get("attributes").equals( + currentDomain.getOptions().get("attributes") + ) + ) { + st.execute(MessageFormat.format( + "DROP DOMAIN IF EXISTS {0}._deprecated_{1} RESTRICT;\n" + + "ALTER DOMAIN {0}.{1} RENAME TO _deprecated_{1};\n" + + "{2}", + currentDomain.getSchema(), currentDomain.getName(), getDdlEscaped(restoreDomain) + )); + } else { + if (! DBGitConfig.getInstance().getToIgnoreOnwer(false)) { + st.execute(getChangeOwnerDdl(currentDomain, restoreDomain.getOwner())); + } + } + } else { + st.execute(getDdlEscaped(restoreDomain)); + } + + } catch (Exception e) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), + e + ); + } finally { + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + return true; + } + + @Override + public void removeMetaObject(IMetaObject obj) throws Exception { + final IDBAdapter adapter = getAdapter(); + final Connection connect = adapter.getConnection(); + + try (StatementLogging st = new StatementLogging( + connect, + adapter.getStreamOutputSqlCommand(), + adapter.isExecSql() + )) { + + final DBSQLObject currentObject = (DBSQLObject) obj.getUnderlyingDbObject(); + st.execute(MessageFormat.format( + "DROP DOMAIN IF EXISTS {0}.{1} RESTRICT", + adapter.escapeNameIfNeeded(getPhisicalSchema(currentObject.getSchema())), + adapter.escapeNameIfNeeded(currentObject.getName()) + )); + + } catch (Exception e) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "objectRemoveError") + .withParams(obj.getName()), e); + } + } + + private String getDdlEscaped(DBSQLObject dbsqlObject) { + String query = dbsqlObject.getSql(); + final String name = dbsqlObject.getName(); + final String schema = dbsqlObject.getSchema(); + final String nameEscaped = adapter.escapeNameIfNeeded(name); + final String schemaEscaped = adapter.escapeNameIfNeeded(schema); + + if (! name.equalsIgnoreCase(nameEscaped)) { + query = query.replace( + "CREATE DOMAIN " + schema + "." + name, + "CREATE DOMAIN " + schemaEscaped + "." + nameEscaped + ); + } + if (! query.endsWith(";")) query = query + ";\n"; + query = query + "\n"; + return query; + } + + private String getChangeOwnerDdl(DBSQLObject dbsqlObject, String owner) { + return MessageFormat.format("ALTER TYPE {0}.{1} OWNER TO {2}\n" + , adapter.escapeNameIfNeeded(dbsqlObject.getSchema()) + , adapter.escapeNameIfNeeded(dbsqlObject.getName()) + , owner + ); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreEnumPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreEnumPostgres.java new file mode 100644 index 0000000..f781be4 --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreEnumPostgres.java @@ -0,0 +1,112 @@ +package ru.fusionsoft.dbgit.postgres; + +import java.sql.Connection; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.DBGitConfig; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; +import ru.fusionsoft.dbgit.dbobjects.DBEnum; +import ru.fusionsoft.dbgit.dbobjects.DBSQLObject; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaEnum; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class DBRestoreEnumPostgres extends DBRestoreAdapter { + @Override + public final boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + final IDBAdapter adapter = getAdapter(); + final Connection connect = adapter.getConnection(); + try (StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql())) { + if (! ( obj instanceof MetaEnum )) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "metaTypeError") + .withParams(obj.getName(), "enum", obj.getType().getValue()) + ); + } + final DBSQLObject restoreEnum = (DBSQLObject) obj.getUnderlyingDbObject(); + final Map enums = adapter.getEnums(restoreEnum.getSchema()); + + if(enums.containsKey(restoreEnum.getName())) { + DBEnum currentEnum = enums.get(restoreEnum.getName()); + if( + ! restoreEnum.getOptions().get("elements").equals( + currentEnum.getOptions().get("elements") + ) + ) { + st.execute(MessageFormat.format( + "ALTER TYPE {0}.{1} RENAME TO _deprecated_{1};\n{2}", + currentEnum.getSchema(), currentEnum.getName(), getDdlEscaped(restoreEnum) + )); + } else{ + if (! DBGitConfig.getInstance().getToIgnoreOnwer(false)) { + st.execute(getChangeOwnerDdl(currentEnum, restoreEnum.getOwner())); + } + } + } else { + st.execute(getDdlEscaped(restoreEnum)); + } + + } catch (Exception e) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), + e + ); + } finally { + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + return true; + } + + @Override + public void removeMetaObject(IMetaObject obj) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + + try (StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql())){ + + final DBSQLObject currentObject = (DBSQLObject) obj.getUnderlyingDbObject(); + st.execute(MessageFormat.format( + "DROP TYPE {0}.{1}", + adapter.escapeNameIfNeeded(getPhisicalSchema(currentObject.getSchema())), + adapter.escapeNameIfNeeded(currentObject.getName()) + )); + + } catch (Exception e) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "objectRemoveError") + .withParams(obj.getName()), e); + } + } + + private String getDdlEscaped(DBSQLObject dbsqlObject) { + String query = dbsqlObject.getSql(); + final String name = dbsqlObject.getName(); + final String schema = dbsqlObject.getSchema(); + final String nameEscaped = adapter.escapeNameIfNeeded(name); + final String schemaEscaped = adapter.escapeNameIfNeeded(schema); + + if (! name.equalsIgnoreCase(nameEscaped)) { + query = query.replace( + "CREATE TYPE " + schema + "." + name, + "CREATE TYPE " + schemaEscaped + "." + nameEscaped + ); + } + if (! query.endsWith(";")) query = query + ";\n"; + query = query + "\n"; + return query; + } + + private String getChangeOwnerDdl(DBSQLObject dbsqlObject, String owner) { + return MessageFormat.format("ALTER TYPE {0}.{1} OWNER TO {2}\n" + , adapter.escapeNameIfNeeded(dbsqlObject.getSchema()) + , adapter.escapeNameIfNeeded(dbsqlObject.getName()) + , owner + ); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableDataPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableDataPostgres.java index a303494..4b5da5c 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableDataPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableDataPostgres.java @@ -77,6 +77,13 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { if (getAdapter().getTable(schema, currentTableData.getTable().getName()) != null) { //actually load data from database currentTableData.setDataTable(getAdapter().getTableData(schema, currentTableData.getTable().getName())); + currentTableData.setFields( + getAdapter().getTableFields(schema, currentTableData.getTable().getName()) + .entrySet().stream() + .sorted(Comparator.comparing(x->x.getValue().getOrder())) + .map( x->x.getKey() ) + .collect(Collectors.toList()) + ); ResultSet rs = currentTableData.getDataTable().resultSet(); @@ -127,23 +134,14 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } public void restoreTableDataPostgres(MetaTableData restoreTableData, MetaTableData currentTableData) throws Exception{ - List fieldsList = restoreTableData.getFields(); -// System.err.println("fieldsList = " + String.join(",", fieldsList)); - if(fieldsList.size() == 0 ) { - ConsoleWriter.printlnRed(DBGitLang.getInstance() - .getValue("errors", "restore", "emptyFieldsList") - , 1 - ); - ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); - return; + //if empty restore table data -> delete all currentTableData + if (currentTableData.getFields().size() == 0 ) { + final CharSequence msg = DBGitLang.getInstance().getValue("errors", "restore", "currentFieldsListIsEmpty").toString(); + throw new ExceptionDBGit(msg); } if (restoreTableData.getmapRows() == null) { - ConsoleWriter.printlnRed(DBGitLang.getInstance() - .getValue("errors", "restore", "emptyRowsList") - , 1 - ); - ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); - return; + final CharSequence msg = DBGitLang.getInstance().getValue("errors", "restore", "emptyRowsList").toString(); + throw new ExceptionDBGit(msg); } IDBAdapter adapter = getAdapter(); @@ -170,10 +168,15 @@ public void restoreTableDataPostgres(MetaTableData restoreTableData, MetaTableDa StringJoiner fieldJoiner = new StringJoiner(","); StringJoiner valuejoiner = new StringJoiner(","); - for( Map.Entry entry : rowData.getData(fieldsList).entrySet()) { + for( Map.Entry entry : rowData.getData(currentTableData.getFields()).entrySet()) { if (keyNames.contains(entry.getKey())) { fieldJoiner.add("\"" + entry.getKey() + "\""); - valuejoiner.add(entry.getValue().convertToString()); + final String value = entry.getValue().convertToString(); + if( value.matches("-?\\d+(\\.0)?") ) { + valuejoiner.add( String.valueOf( (long) Double.parseDouble(value) ) ); + } else { + valuejoiner.add("'" + value + "'"); + } } } @@ -200,7 +203,6 @@ public void restoreTableDataPostgres(MetaTableData restoreTableData, MetaTableDa } //UPDATE - ConsoleWriter.detailsPrintln("Entries differing count: " + diffTableData.entriesDiffering().keySet().size(), messageLevel); if (!diffTableData.entriesDiffering().isEmpty()) { ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "updating"), messageLevel); String updateQuery = ""; @@ -209,7 +211,7 @@ public void restoreTableDataPostgres(MetaTableData restoreTableData, MetaTableDa for (ValueDifference diffRowData : diffTableData.entriesDiffering().values()) { if (!diffRowData.leftValue().getHashRow().equals(diffRowData.rightValue().getHashRow())) { - Map tempCols = diffRowData.leftValue().getData(fieldsList); + Map tempCols = diffRowData.leftValue().getData(restoreTableData.getFields()); for (String key : tempCols.keySet()) { if (tempCols.get(key) == null || tempCols.get(key).convertToString() == null) continue; if (keyNames.contains(key)) { @@ -236,7 +238,7 @@ public void restoreTableDataPostgres(MetaTableData restoreTableData, MetaTableDa updateQuery = "UPDATE " + tblNameEscaped + " SET (" + updFieldJoiner.toString() + ") = " - + valuesToString(tempCols.values(), colTypes, fieldsList) + " " + + valuesToString(tempCols.values(), colTypes, restoreTableData.getFields()) + " " + "WHERE (" + keyFieldsJoiner.toString() + ") = (" + keyValuesJoiner.toString() + ");\n"; @@ -262,7 +264,7 @@ public void restoreTableDataPostgres(MetaTableData restoreTableData, MetaTableDa String insertQuery = MessageFormat.format("INSERT INTO {0}{1}{2};" , tblNameEscaped, fields - , valuesToString(rowData.getData(fieldsList).values(), colTypes, fieldsList) + , valuesToString(rowData.getData(restoreTableData.getFields()).values(), colTypes, restoreTableData.getFields()) ); ConsoleWriter.detailsPrintln(insertQuery, messageLevel+1); diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTablePostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTablePostgres.java index 3627acc..a7ff235 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTablePostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTablePostgres.java @@ -324,6 +324,8 @@ private void restoreTableFields(MetaTable restoreTable, MetaTable existingTable, &&(restoreField.getTypeUniversal() != FieldType.BOOLEAN) &&(existingField.getTypeUniversal() != FieldType.STRING_NATIVE) &&(restoreField.getTypeUniversal() != FieldType.STRING_NATIVE) + &&(existingField.getTypeUniversal() != FieldType.NATIVE) + &&(restoreField.getTypeUniversal() != FieldType.NATIVE) && hasNotTypeSql(tblField, "json") && hasNotTypeSql(tblField, "text[]") && hasNotTypeSql(tblField, "text") diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreUDTPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreUDTPostgres.java new file mode 100644 index 0000000..14e206c --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreUDTPostgres.java @@ -0,0 +1,117 @@ +package ru.fusionsoft.dbgit.postgres; + +import java.sql.Connection; +import java.text.MessageFormat; +import java.util.Map; +import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.DBGitConfig; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; +import ru.fusionsoft.dbgit.dbobjects.DBSQLObject; +import ru.fusionsoft.dbgit.dbobjects.DBUserDefinedType; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaUDT; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class DBRestoreUDTPostgres extends DBRestoreAdapter { + @Override + public final boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + final IDBAdapter adapter = getAdapter(); + final Connection connect = adapter.getConnection(); + try (final StatementLogging st = new StatementLogging( + connect, + adapter.getStreamOutputSqlCommand(), + adapter.isExecSql() + )) { + if (! ( obj instanceof MetaUDT )) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "metaTypeError").withParams(obj.getName(), "udt", obj.getType().getValue()) + ); + } + final DBSQLObject restoreUDT = (DBSQLObject) obj.getUnderlyingDbObject(); + final Map udts = adapter.getUDTs(restoreUDT.getSchema()); + + if (udts.containsKey(restoreUDT.getName())) { + final DBUserDefinedType currentUDT = udts.get(restoreUDT.getName()); + if ( + ! restoreUDT.getOptions().get("attributes").equals( + currentUDT.getOptions().get("attributes") + ) + ) { + st.execute(MessageFormat.format( + "ALTER TYPE {0}.{1} RENAME TO _deprecated_{1};\n" + + "{2}", + currentUDT.getSchema(), currentUDT.getName(), getDdlEscaped(restoreUDT) + )); + } else { + if (! DBGitConfig.getInstance().getToIgnoreOnwer(false)) { + st.execute(getChangeOwnerDdl(currentUDT, restoreUDT.getOwner())); + } + } + } else { + st.execute(getDdlEscaped(restoreUDT)); + } + + } catch (Exception e) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), + e + ); + } finally { + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + return true; + } + + @Override + public void removeMetaObject(IMetaObject obj) throws Exception { + final IDBAdapter adapter = getAdapter(); + final Connection connect = adapter.getConnection(); + + try (StatementLogging st = new StatementLogging( + connect, + adapter.getStreamOutputSqlCommand(), + adapter.isExecSql() + )) { + + final DBSQLObject currentObject = (DBSQLObject) obj.getUnderlyingDbObject(); + st.execute(MessageFormat.format( + "DROP TYPE {0}.{1}", + adapter.escapeNameIfNeeded(getPhisicalSchema(currentObject.getSchema())), + adapter.escapeNameIfNeeded(currentObject.getName()) + )); + + } catch (Exception e) { + throw new ExceptionDBGitRestore( + lang.getValue("errors", "restore", "objectRemoveError") + .withParams(obj.getName()), e); + } + } + + private String getDdlEscaped(DBSQLObject dbsqlObject) { + String query = dbsqlObject.getSql(); + final String name = dbsqlObject.getName(); + final String schema = dbsqlObject.getSchema(); + final String nameEscaped = adapter.escapeNameIfNeeded(name); + final String schemaEscaped = adapter.escapeNameIfNeeded(schema); + + if (! name.equalsIgnoreCase(nameEscaped)) { + query = query.replace( + "CREATE TYPE " + schema + "." + name, + "CREATE TYPE " + schemaEscaped + "." + nameEscaped + ); + } + if (! query.endsWith(";")) query = query + ";\n"; + query = query + "\n"; + return query; + } + + private String getChangeOwnerDdl(DBSQLObject dbsqlObject, String owner) { + return MessageFormat.format("ALTER TYPE {0}.{1} OWNER TO {2}\n" + , adapter.escapeNameIfNeeded(dbsqlObject.getSchema()) + , adapter.escapeNameIfNeeded(dbsqlObject.getName()) + , owner + ); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/FactoryDBAdapterRestorePostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/FactoryDBAdapterRestorePostgres.java index a9e8f3f..c7c7e1a 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/FactoryDBAdapterRestorePostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/FactoryDBAdapterRestorePostgres.java @@ -22,6 +22,9 @@ public class FactoryDBAdapterRestorePostgres implements IFactoryDBAdapterRestote static { Map aMap = new HashMap(); aMap.put(DBGitMetaType.DBGitSchema.getValue(), new DBRestoreSchemaPostgres()); + aMap.put(DBGitMetaType.DBGitUserDefinedType.getValue(), new DBRestoreUDTPostgres()); + aMap.put(DBGitMetaType.DBGitDomain.getValue(), new DBRestoreDomainPostgres()); + aMap.put(DBGitMetaType.DBGitEnum.getValue(), new DBRestoreEnumPostgres()); aMap.put(DBGitMetaType.DBGitTableSpace.getValue(), new DBRestoreTableSpacePostgres()); aMap.put(DBGitMetaType.DBGitRole.getValue(), new DBRestoreRolePostgres()); aMap.put(DBGitMetaType.DBGitSequence.getValue(), new DBRestoreSequencePostgres()); diff --git a/src/main/resources/lang/eng.yaml b/src/main/resources/lang/eng.yaml index d7e0f72..1a3e5db 100644 --- a/src/main/resources/lang/eng.yaml +++ b/src/main/resources/lang/eng.yaml @@ -73,6 +73,9 @@ general: restoreTrigger: Restoring trigger {0} ... restoreSeq: Restoring sequence {0} ... restoreSchema: Restoring schema {0} ... + restoreUDT: Restoring user defined type {0} ... + restoreEnum: Restoring enum {0} ... + restoreDomain: Restoring domain {0} ... restoreRole: Restoring role {0} ... restorePrc: Restoring procedure {0} ... restorePkg: Restoring package {0} ... @@ -203,7 +206,7 @@ errors: cantConnect: Can't connect to db! errorLoadDelete: Error load and delete object fileAlreadyExists: Error write script, file {0} already exists - emptyFieldsList: Empty fieldList, maybe empty csv... + currentFieldsListIsEmpty: Empty fieldList in current table which means the table is not reconstructed properly... emptyRowsList: MapRows is null, maybe empty csv... add: badCommand: Bad command. Not found object to add! diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestBasic.java b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestBasic.java index 9928fb6..fdffffe 100644 --- a/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestBasic.java +++ b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestBasic.java @@ -19,7 +19,10 @@ import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitAddRemoteTestRepo; import ru.fusionsoft.dbgit.integration.primitives.chars.CommitsFromRepo; import ru.fusionsoft.dbgit.integration.primitives.chars.LinesOfUnsafeScalar; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit.CharsDbIgnoreWithDataAndTypes; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit.CharsDbGitConfigBackupEnabled; import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitCheckout; +import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitCheckoutHard; import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitClonesRepo; import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitRestore; import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOfConsoleWhenRunning; @@ -153,10 +156,10 @@ public final void dbToFilesDumpWorks() { new ArgsExplicit("add", "\"*\""), new PathWithFiles( - new PathPatchCreatingFile(".dbgit/.dbignore", new CharsDbIgnoreWithTableData()), + new PathPatchCreatingFile(".dbgit/.dbignore", new CharsDbIgnoreWithDataAndTypes()), new PathAfterDbGitRun( - new ArgsDbGitLinkPgAuto("pagilla"), + new ArgsDbGitLinkPgAuto("dvdrental"), new PathAfterDbGitRun( new ArgsExplicit("init"), @@ -186,9 +189,27 @@ public final void dbToFilesDumpWorks() { } ), new SimpleTest<>( - "rental table data (10K+ rows) is not empty", + "rental table data (10K+ rows) exists and is empty", + (path) -> { + return Files.readAllLines(path.resolve(".dbgit/public/rental.csv")).isEmpty(); + } + ), + new SimpleTest<>( + "mpaa_rating.enum exists", + (path) -> { + return path.resolve(".dbgit/public/mpaa_rating.enum").toFile().exists(); + } + ), + new SimpleTest<>( + "year.domain exists", + (path) -> { + return path.resolve(".dbgit/public/year.domain").toFile().exists(); + } + ), + new SimpleTest<>( + "film_summary.udt exists", (path) -> { - return ! Files.readAllLines(path.resolve(".dbgit/public/rental.csv")).isEmpty(); + return path.resolve(".dbgit/public/film_summary.udt").toFile().exists(); } ) ); @@ -251,12 +272,15 @@ public final void gitToDbRestoreWorks() throws Exception { new PathPatchDbGitCheckout(nameOfSourceBranch, "-b", "-nodb"), new PathPatchDbGitCheckout(commitNames.get(0), "-nodb", "-v"), new PathPatchDbGitLink(linkArgs), + new PathPatchCreatingFile(".dbgit/dbgitconfig", new CharsDbGitConfigBackupEnabled()), new PathPatchDbGitRestore("-r", "-v"), - new PathPatchDbGitCheckout(commitNames.get(1), "-nodb", "-v"), + new PathPatchDbGitCheckoutHard(commitNames.get(1), "-nodb", "-v"), new PathPatchDbGitLink(linkArgs), + new PathPatchCreatingFile(".dbgit/dbgitconfig", new CharsDbGitConfigBackupEnabled()), new PathPatchDbGitRestore("-r", "-v"), - new PathPatchDbGitCheckout(commitNames.get(2), "-nodb", "-v"), + new PathPatchDbGitCheckoutHard(commitNames.get(2), "-nodb", "-v"), new PathPatchDbGitLink(linkArgs), + new PathPatchCreatingFile(".dbgit/dbgitconfig", new CharsDbGitConfigBackupEnabled()), new PathPatchDbGitRestore("-r", "-v") ), new ProjectTestResourcesCleanDirectoryPath("04") @@ -290,7 +314,7 @@ public final void dbToDbRestoreWorksWithCustomTypes() { //pagilla to local repo new PathAfterDbGitLinkAndAdd( new ArgsDbGitLinkPgAuto("pagilla"), - new CharsDbIgnoreWithTableData(), + new CharsDbIgnoreWithDataAndTypes(), //dvdrental to test#databasegit new PathAfterDbGitRun( @@ -302,7 +326,7 @@ public final void dbToDbRestoreWorksWithCustomTypes() { //dvdrental to local repo new PathAfterDbGitLinkAndAdd( new ArgsDbGitLinkPgAuto("dvdrental"), - new CharsDbIgnoreWithTableData(), + new CharsDbIgnoreWithDataAndTypes(), new PathAfterDbGitRun( new ArgsExplicit("init"), diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestNotebook.java b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestNotebook.java index b60b53c..218bebc 100644 --- a/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestNotebook.java +++ b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestNotebook.java @@ -3,6 +3,7 @@ import java.nio.file.Path; import java.text.MessageFormat; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; @@ -29,6 +30,7 @@ import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.scenarios.PathAfterDbGitDumpsDbSchemaToGit; @Tag("notebook") +@Disabled public class DbGitIntegrationTestNotebook { @Test public final void appendsDbSchemaToBranchOfTestRepo() { diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/SelfTest.java b/src/test/java/ru/fusionsoft/dbgit/integration/SelfTest.java index da85706..73eacc6 100644 --- a/src/test/java/ru/fusionsoft/dbgit/integration/SelfTest.java +++ b/src/test/java/ru/fusionsoft/dbgit/integration/SelfTest.java @@ -67,11 +67,8 @@ public final void failsToFalseOnException() { new Patch() { @Override public void apply(Path root) throws Exception { - System.out.println("access " - + root.toString()); - throw new Error( - "dummy error" - ); + System.out.println("access " + root.toString()); + throw new RuntimeException("dummy error"); } } ), diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbGitConfigBackupEnabled.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbGitConfigBackupEnabled.java new file mode 100644 index 0000000..c1f79ed --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbGitConfigBackupEnabled.java @@ -0,0 +1,22 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit; + +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public class CharsDbGitConfigBackupEnabled extends CharSequenceEnvelope { + public CharsDbGitConfigBackupEnabled() { + super(() -> { + return "[core]\n" + + "MAX_ROW_COUNT_FETCH = 10000\n" + + "LIMIT_FETCH = true\n" + + "LOG_ROTATE = 31\n" + + "LANG = ENG\n" + + "SCRIPT_ROTATE = 31\n" + + "TO_MAKE_BACKUP = true\n" + + "BACKUP_TO_SCHEME = true\n" + + "BACKUP_TABLEDATA = true\n" + + "PORTION_SIZE = 50000\n" + + "TRY_COUNT = 1000\n" + + "TRY_DELAY = 10\n"; + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbGitConfigDefault.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbGitConfigDefault.java new file mode 100644 index 0000000..09e219e --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbGitConfigDefault.java @@ -0,0 +1,22 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit; + +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public class CharsDbGitConfigDefault extends CharSequenceEnvelope { + public CharsDbGitConfigDefault() { + super(()->{ + return "[core]\n" + + "MAX_ROW_COUNT_FETCH = 10000\n" + + "LIMIT_FETCH = true\n" + + "LOG_ROTATE = 31\n" + + "LANG = ENG\n" + + "SCRIPT_ROTATE = 31\n" + + "TO_MAKE_BACKUP = false\n" + + "BACKUP_TO_SCHEME = true\n" + + "BACKUP_TABLEDATA = true\n" + + "PORTION_SIZE = 50000\n" + + "TRY_COUNT = 1000\n" + + "TRY_DELAY = 10\n"; + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbIgnoreWithDataAndTypes.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbIgnoreWithDataAndTypes.java new file mode 100644 index 0000000..c3725d4 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbIgnoreWithDataAndTypes.java @@ -0,0 +1,25 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit; + +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public class CharsDbIgnoreWithDataAndTypes extends CharSequenceEnvelope { + public CharsDbIgnoreWithDataAndTypes() { + super(()->{ + return "*\n" + + "!public/*.ts\n" + + "!public/*.sch\n" + + "!public/*.seq\n" + + "!public/*.tbl\n" + + "!public/*.pkg\n" + + "!public/*.trg\n" + + "!public/*.prc\n" + + "!public/*.fnc\n" + + "!public/*.vw\n" + + "!public/*.blob\n" + + "!public/*.udt\n" + + "!public/*.enum\n" + + "!public/*.domain\n" + + "!public/*.csv\n"; + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckoutHard.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckoutHard.java new file mode 100644 index 0000000..502985a --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckoutHard.java @@ -0,0 +1,22 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch.specific; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitCheckout; + +public class PathPatchDbGitCheckoutHard extends PatchSequential { + public PathPatchDbGitCheckoutHard(ArgsDbGitCheckout argsDbGitCheckout, PrintStream printStream) { + super( + new PathPatchDbGitReset("-hard"), + new PathPatchDbGitCheckout(argsDbGitCheckout, printStream) + ); + } + + public PathPatchDbGitCheckoutHard(CharSequence... checkoutArgs) { + super( + new PathPatchDbGitReset("-hard"), + new PathPatchDbGitCheckout(new ArgsDbGitCheckout(checkoutArgs)) + ); + } +}