diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..b68384b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,30 @@ +image: maven:3.6.3-jdk-8 + +stages: + - test + - build + +include: + - template: Security/SAST.gitlab-ci.yml + +build: + stage: build + script: + - time mvn package appassembler:assemble -D skipTests + - mv target/dbgit dbgit + only: + refs: + - master + artifacts: + expire_in: never + paths: + - dbgit +test: + stage: test + script: + - time mvn test + allow_failure: true + +cache: + paths: + - .m2/repository diff --git a/.rultor.yml b/.rultor.yml new file mode 100644 index 0000000..54df89d --- /dev/null +++ b/.rultor.yml @@ -0,0 +1,16 @@ +env: + MAVEN_OPTS: "-XX:MaxPermSize=256m -Xmx1g" +assets: + pgSecret.txt: rocket-3/dbgit-test#pgSecret.txt + gitSecret.txt: rocket-3/dbgit-test#gitSecret.txt +install: |- + java -version --batch-mode + mvn -version --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: |- + mvn test -Dtest=${tests:-'*selfTest,*DbGitIntegrationTestBasic*'} --batch-mode diff --git a/pom.xml b/pom.xml index 5d3197f..d0efc3f 100644 --- a/pom.xml +++ b/pom.xml @@ -8,6 +8,12 @@ jar + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + org.apache.maven.plugins @@ -68,7 +74,23 @@ + + + false + ${project.basedir}/src/main/resources + + logback-test.xml + + + + + + ${project.basedir}/src/main/resources/ + + logback.xml + + ${project.basedir}/src/main/resources/scripts ${project.build.directory}/dbgit @@ -98,8 +120,15 @@ - ${project.basedir}/src/main/resources - ${project.build.directory}/dbgit + ${project.basedir}/src/main/resources/example + ${project.build.directory}/dbgit/example + + .dblink + + + + ${project.basedir}/src/main/resources/ + ${project.build.directory}/dbgit/ dbgitconfig @@ -117,14 +146,6 @@ - - - junit - junit - 4.12 - test - - @@ -195,6 +216,11 @@ 1.4 + + org.junit.jupiter + junit-jupiter + 5.7.2 + @@ -230,12 +256,12 @@ - com.oracle.jdbc + com.oracle.ojdbc ojdbc8 - 18.3.0.0 + 19.3.0.0 - + com.microsoft.sqlserver mssql-jdbc 7.0.0.jre8 @@ -246,6 +272,12 @@ jsr305 3.0.0 + + org.junit.platform + junit-platform-commons + 1.7.0 + compile + diff --git a/src/main/java/de/siegmar/fastcsv/reader/CsvContainer.java b/src/main/java/de/siegmar/fastcsv/reader/CsvContainer.java new file mode 100644 index 0000000..e638e0a --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/reader/CsvContainer.java @@ -0,0 +1,76 @@ +/* + * Copyright 2015 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.reader; + +import java.util.Collections; +import java.util.List; + +/** + * Class for holding a complete CSV file. + * + * @author Oliver Siegmar + */ +public final class CsvContainer { + + private final List header; + private final List rows; + + CsvContainer(final List header, final List rows) { + this.header = header; + this.rows = rows; + } + + /** + * Returns the number of rows in this container. + * + * @return the number of rows in this container + */ + public int getRowCount() { + return rows.size(); + } + + /** + * Returns the header row - might be {@code null} if no header exists. + * The returned list is unmodifiable. + * + * @return the header row - might be {@code null} if no header exists + */ + public List getHeader() { + return header; + } + + /** + * Returns a CsvRow by its index (starting with 0). + * + * @param index index of the row to return + * @return the row by its index + * @throws IndexOutOfBoundsException if index is out of range + */ + public CsvRow getRow(final int index) { + return rows.get(index); + } + + /** + * Returns an unmodifiable list of rows. + * + * @return an unmodifiable list of rows + */ + public List getRows() { + return Collections.unmodifiableList(rows); + } + +} diff --git a/src/main/java/de/siegmar/fastcsv/reader/CsvParser.java b/src/main/java/de/siegmar/fastcsv/reader/CsvParser.java new file mode 100644 index 0000000..19bb1b4 --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/reader/CsvParser.java @@ -0,0 +1,144 @@ +/* + * Copyright 2015 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.reader; + +import java.io.Closeable; +import java.io.IOException; +import java.io.Reader; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * This class is responsible for parsing CSV data from the passed-in Reader. + * + * @author Oliver Siegmar + */ +public final class CsvParser implements Closeable { + + private final RowReader rowReader; + private final boolean containsHeader; + private final boolean skipEmptyRows; + private final boolean errorOnDifferentFieldCount; + + private Map headerMap; + private List headerList; + private long lineNo; + private int firstLineFieldCount = -1; + + CsvParser(final Reader reader, final char fieldSeparator, final char textDelimiter, + final boolean containsHeader, final boolean skipEmptyRows, + final boolean errorOnDifferentFieldCount) { + + rowReader = new RowReader(reader, fieldSeparator, textDelimiter); + this.containsHeader = containsHeader; + this.skipEmptyRows = skipEmptyRows; + this.errorOnDifferentFieldCount = errorOnDifferentFieldCount; + } + + /** + * Returns the header fields - {@code null} if no header exists. The returned list is + * unmodifiable. Use {@link CsvReader#setContainsHeader(boolean)} to enable header parsing. + * Also note, that the header is only available after first invocation of + * {@link #nextRow()}. + * + * @return the header fields + * @throws IllegalStateException if header parsing is not enabled or {@link #nextRow()} wasn't + * called before. + */ + public List getHeader() { + if (!containsHeader) { + throw new IllegalStateException("No header available - header parsing is disabled"); + } + if (lineNo == 0) { + throw new IllegalStateException("No header available - call nextRow() first"); + } + return headerList; + } + + /** + * Reads a complete {@link CsvRow} that might be made up of multiple lines in the underlying + * CSV file. + * + * @return a CsvRow or {@code null} if end of file reached + * @throws IOException if an error occurred while reading data + */ + public CsvRow nextRow() throws IOException { + while (!rowReader.isFinished()) { + final long startingLineNo = lineNo + 1; + final RowReader.Line line = rowReader.readLine(); + final String[] currentFields = line.getFields(); + lineNo += line.getLines(); + + final int fieldCount = currentFields.length; + + // reached end of data in a new line? + if (fieldCount == 0) { + break; + } + + // skip empty rows + if (skipEmptyRows && fieldCount == 1 && currentFields[0].isEmpty()) { + continue; + } + + // check the field count consistency on every row + if (errorOnDifferentFieldCount) { + if (firstLineFieldCount == -1) { + firstLineFieldCount = fieldCount; + } else if (fieldCount != firstLineFieldCount) { + throw new IOException( + String.format("Line %d has %d fields, but first line has %d fields", + lineNo, fieldCount, firstLineFieldCount)); + } + } + + final List fieldList = Arrays.asList(currentFields); + + // initialize header + if (containsHeader && headerList == null) { + initHeader(fieldList); + continue; + } + + return new CsvRow(startingLineNo, headerMap, fieldList); + } + + return null; + } + + private void initHeader(final List currentFields) { + headerList = Collections.unmodifiableList(currentFields); + + final Map localHeaderMap = new LinkedHashMap<>(currentFields.size()); + for (int i = 0; i < currentFields.size(); i++) { + final String field = currentFields.get(i); + if (field != null && !field.isEmpty() && !localHeaderMap.containsKey(field)) { + localHeaderMap.put(field, i); + } + } + headerMap = Collections.unmodifiableMap(localHeaderMap); + } + + @Override + public void close() throws IOException { + rowReader.close(); + } + +} diff --git a/src/main/java/de/siegmar/fastcsv/reader/CsvReader.java b/src/main/java/de/siegmar/fastcsv/reader/CsvReader.java new file mode 100644 index 0000000..9e929b2 --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/reader/CsvReader.java @@ -0,0 +1,206 @@ +/* + * Copyright 2015 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.reader; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * This is the main class for reading CSV data. + * + * @author Oliver Siegmar + */ +public final class CsvReader { + + /** + * Field separator character (default: ',' - comma). + */ + private char fieldSeparator = ','; + + /** + * Text delimiter character (default: '"' - double quotes). + */ + private char textDelimiter = '"'; + + /** + * Read first line as header line? (default: false). + */ + private boolean containsHeader; + + /** + * Skip empty rows? (default: true) + */ + private boolean skipEmptyRows = true; + + /** + * Throw an exception if CSV data contains different field count? (default: false). + */ + private boolean errorOnDifferentFieldCount; + + /** + * Sets the field separator character (default: ',' - comma). + */ + public void setFieldSeparator(final char fieldSeparator) { + this.fieldSeparator = fieldSeparator; + } + + /** + * Sets the text delimiter character (default: '"' - double quotes). + */ + public void setTextDelimiter(final char textDelimiter) { + this.textDelimiter = textDelimiter; + } + + /** + * Specifies if the first line should be the header (default: false). + */ + public void setContainsHeader(final boolean containsHeader) { + this.containsHeader = containsHeader; + } + + /** + * Specifies if empty rows should be skipped (default: true). + */ + public void setSkipEmptyRows(final boolean skipEmptyRows) { + this.skipEmptyRows = skipEmptyRows; + } + + /** + * Specifies if an exception should be thrown, if CSV data contains different field count + * (default: false). + */ + public void setErrorOnDifferentFieldCount(final boolean errorOnDifferentFieldCount) { + this.errorOnDifferentFieldCount = errorOnDifferentFieldCount; + } + + /** + * Reads an entire file and returns a CsvContainer containing the data. + * + * @param file the file to read data from. + * @param charset the character set to use - must not be {@code null}. + * @return the entire file's data - never {@code null}. + * @throws IOException if an I/O error occurs. + */ + public CsvContainer read(final File file, final Charset charset) throws IOException { + return read( + Objects.requireNonNull(file.toPath(), "file must not be null"), + Objects.requireNonNull(charset, "charset must not be null") + ); + } + + /** + * Reads an entire file and returns a CsvContainer containing the data. + * + * @param path the file to read data from. + * @param charset the character set to use - must not be {@code null}. + * @return the entire file's data - never {@code null}. + * @throws IOException if an I/O error occurs. + */ + public CsvContainer read(final Path path, final Charset charset) throws IOException { + Objects.requireNonNull(path, "path must not be null"); + Objects.requireNonNull(charset, "charset must not be null"); + try (final Reader reader = newPathReader(path, charset)) { + return read(reader); + } + } + + /** + * Reads from the provided reader until the end and returns a CsvContainer containing the data. + * + * This library uses built-in buffering, so you do not need to pass in a buffered Reader + * implementation such as {@link java.io.BufferedReader}. + * Performance may be even likely better if you do not. + * + * @param reader the data source to read from. + * @return the entire file's data - never {@code null}. + * @throws IOException if an I/O error occurs. + */ + public CsvContainer read(final Reader reader) throws IOException { + final CsvParser csvParser = + parse(Objects.requireNonNull(reader, "reader must not be null")); + + final List rows = new ArrayList<>(); + CsvRow csvRow; + while ((csvRow = csvParser.nextRow()) != null) { + rows.add(csvRow); + } + + final List header = containsHeader ? csvParser.getHeader() : null; + return new CsvContainer(header, rows); + } + + /** + * Constructs a new {@link CsvParser} for the specified arguments. + * + * @param path the file to read data from. + * @param charset the character set to use - must not be {@code null}. + * @return a new CsvParser - never {@code null}. + * @throws IOException if an I/O error occurs. + */ + public CsvParser parse(final Path path, final Charset charset) throws IOException { + return parse(newPathReader( + Objects.requireNonNull(path, "path must not be null"), + Objects.requireNonNull(charset, "charset must not be null") + )); + } + + /** + * Constructs a new {@link CsvParser} for the specified arguments. + * + * @param file the file to read data from. + * @param charset the character set to use - must not be {@code null}. + * @return a new CsvParser - never {@code null}. + * @throws IOException if an I/O error occurs. + */ + public CsvParser parse(final File file, final Charset charset) throws IOException { + return parse( + Objects.requireNonNull(file, "file must not be null").toPath(), + Objects.requireNonNull(charset, "charset must not be null") + ); + } + + /** + * Constructs a new {@link CsvParser} for the specified arguments. + * + * This library uses built-in buffering, so you do not need to pass in a buffered Reader + * implementation such as {@link java.io.BufferedReader}. + * Performance may be even likely better if you do not. + * + * @param reader the data source to read from. + * @return a new CsvParser - never {@code null}. + * @throws IOException if an I/O error occurs. + */ + public CsvParser parse(final Reader reader) throws IOException { + return new CsvParser(Objects.requireNonNull(reader, "reader must not be null"), + fieldSeparator, textDelimiter, containsHeader, skipEmptyRows, + errorOnDifferentFieldCount); + } + + private static Reader newPathReader(final Path path, final Charset charset) throws IOException { + return new InputStreamReader(Files.newInputStream(path, StandardOpenOption.READ), charset); + } + +} diff --git a/src/main/java/de/siegmar/fastcsv/reader/CsvRow.java b/src/main/java/de/siegmar/fastcsv/reader/CsvRow.java new file mode 100644 index 0000000..cc6e076 --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/reader/CsvRow.java @@ -0,0 +1,165 @@ +/* + * Copyright 2015 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.reader; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * This class represents a single CSV row. + * + * @author Oliver Siegmar + */ +public final class CsvRow { + + /** + * The original line number (empty lines may be skipped). + */ + private final long originalLineNumber; + + private final Map headerMap; + private final List fields; + + CsvRow(final long originalLineNumber, final Map headerMap, + final List fields) { + + this.originalLineNumber = originalLineNumber; + this.headerMap = headerMap; + this.fields = fields; + } + + /** + * Returns the original line number (starting with 1). On multi-line rows this is the starting + * line number. Empty lines could be skipped via {@link CsvReader#setSkipEmptyRows(boolean)}. + * + * @return the original line number + */ + public long getOriginalLineNumber() { + return originalLineNumber; + } + + /** + * Gets a field value by its index (starting with 0). + * + * @param index index of the field to return + * @return field value + * @throws IndexOutOfBoundsException if index is out of range + */ + public String getField(final int index) { + return fields.get(index); + } + + /** + * Gets a field value by its name. + * + * @param name field name + * @return field value, {@code null} if this row has no such field + * @throws IllegalStateException if CSV is read without headers - + * see {@link CsvReader#containsHeader} + */ + public String getField(final String name) { + if (headerMap == null) { + throw new IllegalStateException("No header available"); + } + + final Integer col = headerMap.get(name); + if (col != null && col < fields.size()) { + return fields.get(col); + } + + return null; + } + + /** + * Gets all fields of this row as an unmodifiable List. + * + * @return all fields of this row + */ + public List getFields() { + return Collections.unmodifiableList(fields); + } + + /** + * Gets an unmodifiable map of header names and field values of this row. + * + * The map will always contain all header names - even if their value is {@code null}. + * + * @return an unmodifiable map of header names and field values of this row + * @throws IllegalStateException if CSV is read without headers - see + * {@link CsvReader#containsHeader} + */ + public Map getFieldMap() { + if (headerMap == null) { + throw new IllegalStateException("No header available"); + } + + final Map fieldMap = new LinkedHashMap<>(headerMap.size()); + for (final Map.Entry header : headerMap.entrySet()) { + final String key = header.getKey(); + final Integer col = headerMap.get(key); + final String val = col != null && col < fields.size() ? fields.get(col) : null; + fieldMap.put(key, val); + } + + return Collections.unmodifiableMap(fieldMap); + } + + /** + * Gets the number of fields of this row. + * + * @return the number of fields of this row + */ + public int getFieldCount() { + return fields.size(); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("CsvRow{"); + sb.append("originalLineNumber="); + sb.append(originalLineNumber); + sb.append(", "); + + sb.append("fields="); + if (headerMap != null) { + sb.append('{'); + for (final Iterator> it = + getFieldMap().entrySet().iterator(); it.hasNext();) { + + final Map.Entry entry = it.next(); + sb.append(entry.getKey()); + sb.append('='); + if (entry.getValue() != null) { + sb.append(entry.getValue()); + } + if (it.hasNext()) { + sb.append(", "); + } + } + sb.append('}'); + } else { + sb.append(fields.toString()); + } + + sb.append('}'); + return sb.toString(); + } + +} diff --git a/src/main/java/de/siegmar/fastcsv/reader/ReusableStringBuilder.java b/src/main/java/de/siegmar/fastcsv/reader/ReusableStringBuilder.java new file mode 100644 index 0000000..1938a6e --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/reader/ReusableStringBuilder.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.reader; + +import java.util.Arrays; + +/** + * Resettable / reusable and thus high performance replacement for StringBuilder. + * + * This class is intended for internal use only. + * + * @author Oliver Siegmar + */ + +final class ReusableStringBuilder { + + private static final String EMPTY = ""; + + private char[] buf; + private int pos; + + /** + * Initializes the buffer with the specified capacity. + * + * @param initialCapacity the initial buffer capacity. + */ + ReusableStringBuilder(final int initialCapacity) { + buf = new char[initialCapacity]; + } + + /** + * Appends a character to the buffer, resizing the buffer if needed. + * + * @param c the character to add to the buffer + */ + public void append(final char c) { + if (pos == buf.length) { + buf = Arrays.copyOf(buf, buf.length * 2); + } + buf[pos++] = c; + } + + public void append(final char[] src, final int srcPos, final int length) { + if (pos + length > buf.length) { + int newSize = buf.length * 2; + while (pos + length > newSize) { + newSize *= 2; + } + buf = Arrays.copyOf(buf, newSize); + } + System.arraycopy(src, srcPos, buf, pos, length); + pos += length; + } + + /** + * @return {@code true} if the buffer contains content + */ + public boolean hasContent() { + return pos > 0; + } + + /** + * Returns the string representation of the buffer and resets the buffer. + * + * @return the string representation of the buffer + */ + public String toStringAndReset() { + if (pos > 0) { + final String s = new String(buf, 0, pos); + pos = 0; + return s; + } + return EMPTY; + } + +} diff --git a/src/main/java/de/siegmar/fastcsv/reader/RowReader.java b/src/main/java/de/siegmar/fastcsv/reader/RowReader.java new file mode 100644 index 0000000..a7a2265 --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/reader/RowReader.java @@ -0,0 +1,219 @@ +/* + * Copyright 2018 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.reader; + +import java.io.Closeable; +import java.io.IOException; +import java.io.Reader; +import java.util.Arrays; + +final class RowReader implements Closeable { + + private static final char LF = '\n'; + private static final char CR = '\r'; + private static final int BUFFER_SIZE = 8192; + + private static final int FIELD_MODE_RESET = 0; + private static final int FIELD_MODE_QUOTED = 1; + private static final int FIELD_MODE_NON_QUOTED = 2; + private static final int FIELD_MODE_QUOTE_ON = 4; + private static final int FIELD_MODE_QUOTED_EMPTY = 8; + + private final Reader reader; + private final char fieldSeparator; + private final char textDelimiter; + private final char[] buf = new char[BUFFER_SIZE]; + private final Line line = new Line(32); + private final ReusableStringBuilder currentField = new ReusableStringBuilder(512); + private int bufPos; + private int bufLen; + private int prevChar = -1; + private int copyStart; + private boolean finished; + + RowReader(final Reader reader, final char fieldSeparator, final char textDelimiter) { + this.reader = reader; + this.fieldSeparator = fieldSeparator; + this.textDelimiter = textDelimiter; + } + + /* + * ugly, performance optimized code begins + */ + Line readLine() throws IOException { + // get fields local for higher performance + final Line localLine = line.reset(); + final ReusableStringBuilder localCurrentField = currentField; + final char[] localBuf = buf; + int localBufPos = bufPos; + int localPrevChar = prevChar; + int localCopyStart = copyStart; + + int copyLen = 0; + int fieldMode = FIELD_MODE_RESET; + int lines = 1; + + while (true) { + if (bufLen == localBufPos) { + // end of buffer + + if (copyLen > 0) { + localCurrentField.append(localBuf, localCopyStart, copyLen); + } + bufLen = reader.read(localBuf, 0, localBuf.length); + + if (bufLen < 0) { + // end of data + finished = true; + + if (localPrevChar == fieldSeparator + || (fieldMode & FIELD_MODE_QUOTED_EMPTY) == FIELD_MODE_QUOTED_EMPTY + || localCurrentField.hasContent() + ) { + localLine.addField(localCurrentField.toStringAndReset()); + } + + break; + } + + localCopyStart = localBufPos = copyLen = 0; + } + + final char c = localBuf[localBufPos++]; + + if ((fieldMode & FIELD_MODE_QUOTE_ON) != 0) { + if (c == textDelimiter) { + // End of quoted text + fieldMode &= ~FIELD_MODE_QUOTE_ON; + if (copyLen > 0) { + localCurrentField.append(localBuf, localCopyStart, copyLen); + copyLen = 0; + } else { + fieldMode |= FIELD_MODE_QUOTED_EMPTY; + } + localCopyStart = localBufPos; + } else { + if (c == CR || c == LF && prevChar != CR) { + lines++; + } + copyLen++; + } + } else { + if (c == fieldSeparator) { + if (copyLen > 0) { + localCurrentField.append(localBuf, localCopyStart, copyLen); + copyLen = 0; + } + localLine.addField(localCurrentField.toStringAndReset()); + localCopyStart = localBufPos; + fieldMode = FIELD_MODE_RESET; + } else if (c == textDelimiter && (fieldMode & FIELD_MODE_NON_QUOTED) == 0) { + // Quoted text starts + fieldMode = FIELD_MODE_QUOTED | FIELD_MODE_QUOTE_ON; + + if (localPrevChar == textDelimiter) { + // escaped quote + copyLen++; + } else { + localCopyStart = localBufPos; + } + } else if (c == CR) { + if (copyLen > 0) { + localCurrentField.append(localBuf, localCopyStart, copyLen); + } + localLine.addField(localCurrentField.toStringAndReset()); + localPrevChar = c; + localCopyStart = localBufPos; + break; + } else if (c == LF) { + if (localPrevChar != CR) { + if (copyLen > 0) { + localCurrentField.append(localBuf, localCopyStart, copyLen); + } + localLine.addField(localCurrentField.toStringAndReset()); + localPrevChar = c; + localCopyStart = localBufPos; + break; + } + localCopyStart = localBufPos; + } else { + copyLen++; + if (fieldMode == FIELD_MODE_RESET) { + fieldMode = FIELD_MODE_NON_QUOTED; + } + } + } + + localPrevChar = c; + } + + // restore fields + bufPos = localBufPos; + prevChar = localPrevChar; + copyStart = localCopyStart; + + localLine.setLines(lines); + return localLine; + } + + @Override + public void close() throws IOException { + reader.close(); + } + + public boolean isFinished() { + return finished; + } + + static final class Line { + + private String[] fields; + private int linePos; + private int lines; + + Line(final int initialCapacity) { + fields = new String[initialCapacity]; + } + + Line reset() { + linePos = 0; + lines = 1; + return this; + } + + void addField(final String field) { + if (linePos == fields.length) { + fields = Arrays.copyOf(fields, fields.length * 2); + } + fields[linePos++] = field; + } + + String[] getFields() { + return Arrays.copyOf(fields, linePos); + } + + int getLines() { + return lines; + } + + void setLines(final int lines) { + this.lines = lines; + } + + } + +} diff --git a/src/main/java/de/siegmar/fastcsv/writer/CsvAppender.java b/src/main/java/de/siegmar/fastcsv/writer/CsvAppender.java new file mode 100644 index 0000000..b9401d9 --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/writer/CsvAppender.java @@ -0,0 +1,146 @@ +/* + * Copyright 2015 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.writer; + +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; +import java.io.Writer; + +/** + * This is the main class for writing CSV data. + * + * @author Oliver Siegmar + */ +public final class CsvAppender implements Closeable, Flushable { + + private static final char LF = '\n'; + private static final char CR = '\r'; + + private final Writer writer; + private final char fieldSeparator; + private final char textDelimiter; + private final boolean alwaysDelimitText; + private final char[] lineDelimiter; + + private boolean newline = true; + + CsvAppender(final Writer writer, final char fieldSeparator, final char textDelimiter, + final boolean alwaysDelimitText, final char[] lineDelimiter) { + this.writer = new FastBufferedWriter(writer); + this.fieldSeparator = fieldSeparator; + this.textDelimiter = textDelimiter; + this.alwaysDelimitText = alwaysDelimitText; + this.lineDelimiter = lineDelimiter; + } + + /** + * Appends a field to the current row. Automatically adds field separator and text delimiters + * as required. + * + * @param value the field to append ({@code null} is handled as empty string) + * @throws IOException if a write error occurs + */ + public void appendField(final String value) throws IOException { + if (!newline) { + writer.write(fieldSeparator); + } else { + newline = false; + } + + if (value == null) { + if (alwaysDelimitText) { + writer.write(textDelimiter); + writer.write(textDelimiter); + } + return; + } + + boolean needsTextDelimiter = alwaysDelimitText; + boolean containsTextDelimiter = false; + + for (int i = 0; i < value.length(); i++) { + final char c = value.charAt(i); + if (c == textDelimiter) { + containsTextDelimiter = needsTextDelimiter = true; + break; + } else if (c == fieldSeparator || c == LF || c == CR) { + needsTextDelimiter = true; + } + } + + if (needsTextDelimiter) { + writer.write(textDelimiter); + } + + if (containsTextDelimiter) { + for (int i = 0; i < value.length(); i++) { + final char c = value.charAt(i); + if (c == textDelimiter) { + writer.write(textDelimiter); + } + writer.write(c); + } + } else { + writer.write(value); + } + + if (needsTextDelimiter) { + writer.write(textDelimiter); + } + } + + /** + * Appends a complete line - one or more fields and new line character(s) at the end. + * + * @param values the fields to append ({@code null} values are handled as empty strings) + * @throws IOException if a write error occurs + */ + public void appendLine(final String... values) throws IOException { + for (final String value : values) { + appendField(value); + } + endLine(); + } + + /** + * Appends new line character(s) to the current line. + * + * @throws IOException if a write error occurs + */ + public void endLine() throws IOException { + writer.write(lineDelimiter); + newline = true; + } + + /** + * {@inheritDoc} + */ + @Override + public void close() throws IOException { + writer.close(); + } + + /** + * {@inheritDoc} + */ + @Override + public void flush() throws IOException { + writer.flush(); + } + +} diff --git a/src/main/java/de/siegmar/fastcsv/writer/CsvWriter.java b/src/main/java/de/siegmar/fastcsv/writer/CsvWriter.java new file mode 100644 index 0000000..da1482d --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/writer/CsvWriter.java @@ -0,0 +1,191 @@ +/* + * Copyright 2015 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.writer; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Collection; +import java.util.Objects; + +/** + * This is the main class for writing CSV data. + * + * @author Oliver Siegmar + */ +public final class CsvWriter { + + /** + * Field separator character (default: ',' - comma). + */ + private char fieldSeparator = ','; + + /** + * Text delimiter character (default: '"' - double quotes). + */ + private char textDelimiter = '"'; + + /** + * Should fields always delimited using the {@link #textDelimiter}? (default: false). + */ + private boolean alwaysDelimitText; + + /** + * The line delimiter character(s) to be used (default: {@link System#lineSeparator()}). + */ + private char[] lineDelimiter = System.lineSeparator().toCharArray(); + + /** + * Sets the field separator character (default: ',' - comma). + */ + public void setFieldSeparator(final char fieldSeparator) { + this.fieldSeparator = fieldSeparator; + } + + /** + * Sets the text delimiter character (default: '"' - double quotes). + */ + public void setTextDelimiter(final char textDelimiter) { + this.textDelimiter = textDelimiter; + } + + /** + * Sets if fields should always delimited using the {@link #textDelimiter} (default: false). + */ + public void setAlwaysDelimitText(final boolean alwaysDelimitText) { + this.alwaysDelimitText = alwaysDelimitText; + } + + /** + * Sets the line delimiter character(s) to be used (default: {@link System#lineSeparator()}). + */ + public void setLineDelimiter(final char[] lineDelimiter) { + this.lineDelimiter = lineDelimiter.clone(); + } + + /** + * Writes all specified data to the file. + * + * @param file where the data should be written to. + * @param data lines/columns to be written. + * @throws IOException if a write error occurs + * @throws NullPointerException if file, charset or data is null + */ + public void write(final File file, final Charset charset, final Collection data) + throws IOException { + + write( + Objects.requireNonNull(file, "file must not be null").toPath(), + Objects.requireNonNull(charset, "charset must not be null"), + data + ); + } + + /** + * Writes all specified data to the path. + * + * @param path where the data should be written to. + * @param data lines/columns to be written. + * @throws IOException if a write error occurs + * @throws NullPointerException if path, charset or data is null + */ + public void write(final Path path, final Charset charset, final Collection data) + throws IOException { + + Objects.requireNonNull(path, "path must not be null"); + Objects.requireNonNull(charset, "charset must not be null"); + try (final Writer writer = newWriter(path, charset)) { + write(writer, data); + } + } + + /** + * Writes all specified data to the writer. + * + * @param writer where the data should be written to. + * @param data lines/columns to be written. + * @throws IOException if a write error occurs + * @throws NullPointerException if writer or data is null + */ + public void write(final Writer writer, final Collection data) throws IOException { + Objects.requireNonNull(data, "data must not be null"); + final CsvAppender appender = append(writer); + for (final String[] values : data) { + appender.appendLine(values); + } + appender.flush(); + } + + /** + * Constructs a {@link CsvAppender} for the specified File. + * + * @param file the file to write data to. + * @param charset the character set to be used for writing data to the file. + * @return a new CsvAppender instance + * @throws IOException if a write error occurs + * @throws NullPointerException if file or charset is null + */ + public CsvAppender append(final File file, final Charset charset) throws IOException { + return append( + Objects.requireNonNull(file, "file must not be null").toPath(), + Objects.requireNonNull(charset, "charset must not be null") + ); + } + + /** + * Constructs a {@link CsvAppender} for the specified Path. + * + * @param path the Path (file) to write data to. + * @param charset the character set to be used for writing data to the file. + * @return a new CsvAppender instance + * @throws IOException if a write error occurs + * @throws NullPointerException if path or charset is null + */ + public CsvAppender append(final Path path, final Charset charset) throws IOException { + return append(newWriter( + Objects.requireNonNull(path, "path must not be null"), + Objects.requireNonNull(charset, "charset must not be null") + )); + } + + /** + * Constructs a {@link CsvAppender} for the specified Writer. + * + * This library uses built-in buffering, so you do not need to pass in a buffered Writer + * implementation such as {@link java.io.BufferedWriter}. + * Performance may be even likely better if you do not. + * + * @param writer the Writer to use for writing CSV data. + * @return a new CsvAppender instance + * @throws NullPointerException if writer is null + */ + public CsvAppender append(final Writer writer) { + return new CsvAppender(Objects.requireNonNull(writer, "writer must not be null"), + fieldSeparator, textDelimiter, alwaysDelimitText, lineDelimiter); + } + + private static Writer newWriter(final Path path, final Charset charset) throws IOException { + return new OutputStreamWriter(Files.newOutputStream(path, StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING), charset); + } + +} diff --git a/src/main/java/de/siegmar/fastcsv/writer/FastBufferedWriter.java b/src/main/java/de/siegmar/fastcsv/writer/FastBufferedWriter.java new file mode 100644 index 0000000..bf3805a --- /dev/null +++ b/src/main/java/de/siegmar/fastcsv/writer/FastBufferedWriter.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Oliver Siegmar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.siegmar.fastcsv.writer; + +import java.io.IOException; +import java.io.Writer; + +/** + * Unsynchronized and thus high performance replacement for BufferedWriter. + * + * This class is intended for internal use only. + * + * @author Oliver Siegmar + */ +final class FastBufferedWriter extends Writer { + + private static final int BUFFER_SIZE = 8192; + + private Writer out; + private char[] buf = new char[BUFFER_SIZE]; + private int pos; + + FastBufferedWriter(final Writer writer) { + this.out = writer; + } + + @Override + public void write(final char[] cbuf, final int off, final int len) throws IOException { + if (pos + len >= buf.length) { + flushBuffer(); + } + + if (len >= buf.length) { + out.write(cbuf, off, len); + } else { + System.arraycopy(cbuf, off, buf, pos, len); + pos += len; + } + } + + @Override + public void write(final int c) throws IOException { + if (pos == buf.length) { + flushBuffer(); + } + buf[pos++] = (char) c; + } + + @Override + public void close() throws IOException { + flushBuffer(); + out.close(); + } + + @Override + public void flush() throws IOException { + flushBuffer(); + out.flush(); + } + + private void flushBuffer() throws IOException { + out.write(buf, 0, pos); + pos = 0; + } + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/App.java b/src/main/java/ru/fusionsoft/dbgit/App.java index d72e2c5..0c2f173 100644 --- a/src/main/java/ru/fusionsoft/dbgit/App.java +++ b/src/main/java/ru/fusionsoft/dbgit/App.java @@ -1,108 +1,129 @@ package ru.fusionsoft.dbgit; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.URL; + +import java.sql.Connection; +import java.sql.SQLException; +import java.text.MessageFormat; import org.apache.commons.cli.CommandLine; -import org.slf4j.LoggerFactory; +import org.junit.platform.commons.util.ExceptionUtils; + -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.joran.JoranConfigurator; -import ch.qos.logback.classic.util.ContextInitializer; -import ch.qos.logback.core.joran.spi.JoranException; -import ch.qos.logback.core.util.StatusPrinter; import ru.fusionsoft.dbgit.command.RequestCmd; +import ru.fusionsoft.dbgit.core.DBConnection; import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.DBGitPath; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.LoggerUtil; +public class App { + + public static void main( String[] args ) { + //configureLogback(); + + try { + DBGitPath.createLogDir(); + DBGitPath.deleteOldLogs(); + executeDbGitCommand(args); + } catch (Error | Exception e) { + final String msg = DBGitLang.getInstance() + .getValue("errors", "executionError") + .toString(); + + System.err.println(MessageFormat.format( + "\n{0}: {1}", + msg, + ExceptionUtils.readStackTrace(e) + )); + + LoggerUtil.getGlobalLogger().error(msg, e); + rollbackConnection(); + System.exit(1); + } finally { + DBGitPath.clearTempDir(); + } + + } -/** - * Hello world! - * - */ -public class App -{ public static void executeDbGitCommand(String[] args) throws Exception { RequestCmd cmd = RequestCmd.getInstance(); - CommandLine cmdLine = cmd.parseCommand(args); - if (cmdLine.hasOption('h')) { cmd.printHelpAboutCommand(cmd.getCommand()); - return ; + return; } - cmd.getCurrentCommand().execute(cmdLine); } - - private static void configureLogback() throws JoranException, IOException { - LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); - JoranConfigurator jc = new JoranConfigurator(); - jc.setContext(context); - context.reset(); - - // overriding the log directory property programmatically - String logDirProperty = ".";// ... get alternative log directory location - - context.putProperty("LOG_DIR", logDirProperty); - //System.out.rintln(CProperties.getProperty("log_root_level")); - context.putProperty("log_root_level", "debug"); - - - ClassLoader classLoader = App.class.getClassLoader(); - File file = new File(classLoader.getResource("logback.xml").getFile()); - FileInputStream fis = new FileInputStream(file); - jc.doConfigure(fis); - - - /* - // this assumes that the logback.xml file is in the root of the bundle. - URL logbackConfigFileUrl = new URL("logback.xml"); - jc.doConfigure(logbackConfigFileUrl.openStream()); - */ + + private static void rollbackConnection() { + if (DBConnection.hasInstance()) try { + DBConnection dbConnection = DBConnection.getInstance(); + Connection connection = dbConnection.getConnect(); + if (connection != null && ! connection.isClosed()) { + connection.rollback(); + connection.close(); + } + } catch (Exception ex) { + if (ex instanceof ExceptionDBGit || ex instanceof SQLException) { + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("errors", "onExceptionTransactionRollbackError") + .withParams(ex.getLocalizedMessage()) + , 0 + ); + } else { + ConsoleWriter.printlnRed( + ex.getLocalizedMessage(), + 0 + ); + } + } } - - private static void updateLogback() { - LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); - - ContextInitializer ci = new ContextInitializer(loggerContext); - URL url = ci.findURLOfDefaultConfigurationFile(true); - try { - JoranConfigurator configurator = new JoranConfigurator(); - configurator.setContext(loggerContext); - loggerContext.reset(); - configurator.doConfigure(url); - } catch (JoranException je) { - // StatusPrinter will handle this - } - StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext); - } - - public static void main( String[] args ) throws Exception - { - //configureLogback(); - - try { - DBGitPath.createLogDir(); - DBGitPath.deleteOldLogs(); - - executeDbGitCommand(args); - - } catch (Exception e) { - ConsoleWriter.printlnRed(DBGitLang.getInstance().getValue("errors", "executionError") + ": " + e.getMessage()); - LoggerUtil.getGlobalLogger().error(e.getMessage(), e); - } finally { - DBGitPath.clearTempDir(); - } - - } +// private static void configureLogback() throws JoranException, IOException { +// LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); +// JoranConfigurator jc = new JoranConfigurator(); +// jc.setContext(context); +// context.reset(); +// +// // overriding the log directory property programmatically +// String logDirProperty = ".";// ... get alternative log directory location +// +// context.putProperty("LOG_DIR", logDirProperty); +// //System.out.rintln(CProperties.getProperty("log_root_level")); +// context.putProperty("log_root_level", "debug"); +// +// +// ClassLoader classLoader = App.class.getClassLoader(); +// File file = new File(classLoader.getResource("logback.xml").getFile()); +// FileInputStream fis = new FileInputStream(file); +// jc.doConfigure(fis); +// +// +// /* +// // this assumes that the logback.xml file is in the root of the bundle. +// URL logbackConfigFileUrl = new URL("logback.xml"); +// jc.doConfigure(logbackConfigFileUrl.openStream()); +// */ +// } +// +// private static void updateLogback() { +// LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); +// +// ContextInitializer ci = new ContextInitializer(loggerContext); +// URL url = ci.findURLOfDefaultConfigurationFile(true); +// +// try { +// JoranConfigurator configurator = new JoranConfigurator(); +// configurator.setContext(loggerContext); +// loggerContext.reset(); +// configurator.doConfigure(url); +// } catch (JoranException je) { +// // StatusPrinter will handle this +// } +// StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext); +// } } diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapter.java b/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapter.java index c5f8ac5..ff75722 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapter.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapter.java @@ -1,8 +1,12 @@ package ru.fusionsoft.dbgit.adapters; +import com.axiomalaska.jdbc.NamedParameterPreparedStatement; +import com.diogonunes.jcdp.color.api.Ansi; import ru.fusionsoft.dbgit.core.*; import ru.fusionsoft.dbgit.core.db.FieldType; import ru.fusionsoft.dbgit.data_table.*; +import ru.fusionsoft.dbgit.dbobjects.DBOptionsObject; +import ru.fusionsoft.dbgit.dbobjects.DBRole; import ru.fusionsoft.dbgit.dbobjects.DBTableField; import ru.fusionsoft.dbgit.meta.*; import ru.fusionsoft.dbgit.utils.ConsoleWriter; @@ -11,11 +15,15 @@ import java.io.OutputStream; import java.sql.Connection; import java.sql.ResultSet; +import java.sql.SQLException; import java.sql.Timestamp; import java.text.MessageFormat; -import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -35,29 +43,39 @@ public abstract class DBAdapter implements IDBAdapter { public void setConnection(Connection conn) { connect = conn; } - @Override public Connection getConnection() { try { int maxTriesCount = DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000)); - int pauseTimeSeconds = DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000)); + int pauseTimeSeconds = DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 2)); int currentTry = 0; - if (connect.isValid(0)) + if (connect.isValid(0)){ + connect.setAutoCommit(false); return connect; - - else { - ConsoleWriter.println("Connection lost, trying to reconnect..."); + } else { + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "dbAdapter", "connectionLost") + , messageLevel-1 + ); while (currentTry <= maxTriesCount) { TimeUnit.SECONDS.sleep(pauseTimeSeconds); currentTry++; - ConsoleWriter.println("Try " + currentTry); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "dbAdapter", "reconnectTry") + .withParams(String.valueOf(currentTry)) + , messageLevel + ); DBConnection conn = DBConnection.getInstance(false); if (conn.testingConnection()) { - conn.flushConnection(); +// conn.flushConnection(); conn = DBConnection.getInstance(true); - ConsoleWriter.println("Successful reconnect"); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "dbAdapter", "reconnectTrySuccess") + , messageLevel + ); connect = conn.getConnect(); + connect.setAutoCommit(false); return connect; } } @@ -83,156 +101,102 @@ public OutputStream getStreamOutputSqlCommand() { public Boolean isExecSql() { return isExec; } + @Override public void restoreDataBase(IMapMetaObject updateObjs) throws Exception { Connection connect = getConnection(); DBGitLang lang = DBGitLang.getInstance(); - boolean toMakeBackup = DBGitConfig.getInstance().getBoolean("core", "TO_MAKE_BACKUP", true); - - IMapMetaObject currStep = updateObjs; try { - List tables = new ArrayList(); - List tablesData = new ArrayList(); - - List createdSchemas = new ArrayList(); - List createdRoles = new ArrayList(); - SortedListMetaObject restoreObjs = updateObjs.getSortedList(); - - if(toMakeBackup){ - IDBBackupAdapter ba = getBackupAdapterFactory().getBackupAdapter(this); - ba.backupDatabase(updateObjs); - } + SortedListMetaObject tables = new SortedListMetaObject(updateObjs.values().stream().filter(x->x instanceof MetaTable ).collect(Collectors.toList())); + SortedListMetaObject tablesExists = new SortedListMetaObject(updateObjs.values().stream().filter(x->x instanceof MetaTable && isExists(x)).collect(Collectors.toList())); - for (IMetaObject obj : restoreObjs.sortFromFree()) { - Integer step = 0; + Set createdSchemas = getSchemes().values().stream().map(DBOptionsObject::getName).collect(Collectors.toSet()); + Set createdRoles = getRoles().values().stream().map(DBRole::getName).collect(Collectors.toSet()); - String schemaName = getSchemaName(obj); - if (schemaName != null) { - schemaName = (SchemaSynonym.getInstance().getSchema(schemaName) != null) - ? SchemaSynonym.getInstance().getSchema(schemaName) - : schemaName; - } + // remove table indexes and constraints, which is step(-2) of restoreMetaObject(MetaTable) + ConsoleWriter.println(lang.getValue("general", "restore", "droppingTablesConstraints"), messageLevel); + for (IMetaObject table : tablesExists.sortFromDependencies()) { + ConsoleWriter.println(lang.getValue("general", "restore", "droppingTableConstraints").withParams(table.getName()), messageLevel+1); + getFactoryRestore().getAdapterRestore(DBGitMetaType.DBGitTable, this).restoreMetaObject(table, -2); + } - boolean res = false; + for (IMetaObject obj : updateObjs.getSortedList().sortFromReferenced()) { Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); - DBGitIgnore ignore = DBGitIgnore.getInstance(); - if (step == 0) { - IDBConvertAdapter convertAdapter = getConvertAdapterFactory().getConvertAdapter(obj.getType().getValue()); - - boolean isContainsNative = false; - if (obj instanceof MetaTable) { - MetaTable table = (MetaTable) obj; - for (DBTableField field : table.getFields().values()) { if (field.getTypeUniversal().equals("native")) { isContainsNative = true; break; } } - } + int step = 0; + boolean res = false; - if (isContainsNative) { - ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "restore", "unsupportedTypes").withParams(obj.getName())); - continue; - } - if (convertAdapter != null) { - if (!createdSchemas.contains(schemaName) && schemaName != null) { - createSchemaIfNeed(schemaName); - createdSchemas.add(schemaName); - } - - String ownerName = getOwnerName(obj); - if (!ignore.matchOne("*." + DBGitMetaType.DBGitRole.getValue()) && !getRoles().containsKey(ownerName) && !createdRoles.contains(ownerName) && ownerName != null) { - createRoleIfNeed(ownerName); - createdRoles.add(ownerName); - } - - obj = convertAdapter.convert(getDbType(), getDbVersion(), obj); - } - } - - while (!res) { - if (obj.getDbType() == null) { - ConsoleWriter.println(lang.getValue("errors", "emptyDbType")); - break; - } - - if (getFactoryRestore().getAdapterRestore(obj.getType(), this) == null || - !obj.getDbType().equals(getDbType())) - break; - - if (!createdSchemas.contains(schemaName) && schemaName != null) { - createSchemaIfNeed(schemaName); - createdSchemas.add(schemaName); - } - - String ownerName = getOwnerName(obj); - if (!ignore.matchOne("*." + DBGitMetaType.DBGitRole.getValue()) && !getRoles().containsKey(ownerName) && !createdRoles.contains(ownerName) && ownerName != null) { - createRoleIfNeed(ownerName); - createdRoles.add(ownerName); - } - - if (obj instanceof MetaTable) { - MetaTable table = (MetaTable) obj; - if (!tables.contains(table)) - tables.add(table); - } - - if (obj instanceof MetaTableData) { - MetaTableData tableData = (MetaTableData) obj; - if (!tables.contains(tableData)) - tablesData.add(tableData); - } + IDBAdapterRestoreMetaData restoreAdapter = getFactoryRestore().getAdapterRestore(obj.getType(), this) ; + if(restoreAdapter == null) throw new Exception("restore adapter is null"); +// ConsoleWriter.printlnGreen(lang.getValue("general", "restore", "restoreType").withParams(obj.getType().toString().substring(5), obj.getName())); - //call restoreAdapter.restoreMetaObject with the next 'step' until it returns true - res = getFactoryRestore().getAdapterRestore(obj.getType(), this).restoreMetaObject(obj, step); - step++; + obj = tryConvert(obj); + createRoleIfNeed(obj, createdRoles); + createSchemaIfNeed(obj, createdSchemas); - if (step > 100) { - throw new Exception(lang.getValue("errors", "restore", "restoreErrorDidNotReturnTrue").toString()); - } + while (!res) { + if(step==0) printRestoreMessage(obj); + //if(step!=0) ConsoleWriter.print(" (step " + step + ")"); + res = restoreAdapter.restoreMetaObject(obj, step++); + + if (step > 100) { throw new Exception(lang.getValue("errors", "restore", "restoreErrorDidNotReturnTrue").toString()); } } - Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); - Long diff = timestampAfter.getTime() - timestampBefore.getTime(); - ConsoleWriter.println("(" + diff + " " + lang.getValue("general", "add", "ms") +")"); + + Long timeDiff = new Timestamp(System.currentTimeMillis()).getTime() - timestampBefore.getTime(); +// ConsoleWriter.detailsPrintColor(MessageFormat.format(" ({1} {2})" +// , obj.getName() +// , timeDiff +// , lang.getValue("general", "add", "ms")), 0, Ansi.FColor.CYAN +// ); } - for (MetaTable table : tables) { + // restore table constraints, which is step(-1) of restoreMetaObject(MetaTable) + ConsoleWriter.println(lang.getValue("general", "restore", "restoringTablesConstraints"), messageLevel); + for (IMetaObject table : tables.sortFromReferenced()) { getFactoryRestore().getAdapterRestore(DBGitMetaType.DBGitTable, this).restoreMetaObject(table, -1); } -/* - for (MetaTableData tableData : tablesData) { - getFactoryRestore().getAdapterRestore(DBGitMetaType.DbGitTableData, this).restoreMetaObject(tableData, -2); - } -*/ connect.commit(); } catch (Exception e) { - connect.rollback(); - ConsoleWriter.detailsPrintlnRed(e.getLocalizedMessage()); - e.printStackTrace(); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "restoreError").toString(), e); } finally { - //connect.setAutoCommit(false); - } + } } - + + private void printRestoreMessage(IMetaObject obj) { + String leafName = ""; + if(obj instanceof MetaSequence){ leafName = "restoreSeq"; } + 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"; } + if(obj instanceof MetaUser){ leafName = "restoreUser"; } + if(obj instanceof MetaFunction){ leafName = "restoreFnc"; } + if(obj instanceof MetaTable){ leafName = "restoreTable"; } + if(obj instanceof MetaTableSpace){ leafName = "restoreTablespace"; } + if(obj instanceof MetaTableData){ leafName = "restoreTableData"; } + ConsoleWriter.println(lang.getValue("general", "restore", leafName).withParams(obj.getName()), 2); + } + @Override public void deleteDataBase(IMapMetaObject deleteObjs) throws Exception { deleteDataBase(deleteObjs, false); } - public void deleteDataBase(IMapMetaObject deleteObjs, boolean isDeleteFromIndex) throws Exception { Connection connect = getConnection(); DBGitIndex index = DBGitIndex.getInctance(); try { - //start transaction - boolean toMakeBackup = DBGitConfig.getInstance().getBoolean("core", "TO_MAKE_BACKUP", true); - - List deleteObjsSorted = deleteObjs.getSortedList().sortFromDependant(); - + List deleteObjsSorted = deleteObjs.getSortedList().sortFromDependencies(); for (IMetaObject obj : deleteObjsSorted) { - if (toMakeBackup) { obj = getBackupAdapterFactory().getBackupAdapter(this).backupDBObject(obj); } getFactoryRestore().getAdapterRestore(obj.getType(), this).removeMetaObject(obj); if(isDeleteFromIndex) index.removeItem(obj); } - connect.commit(); } catch (Exception e) { connect.rollback(); @@ -241,27 +205,103 @@ public void deleteDataBase(IMapMetaObject deleteObjs, boolean isDeleteFromIndex) //connect.setAutoCommit(false); } } - + + public String cleanString(String str) { String dt = str.replace("\r\n", "\n"); while (dt.contains(" \n")) dt = dt.replace(" \n", "\n"); dt = dt.replace("\t", " ").trim(); - + return dt; } - - public void rowToProperties(ResultSet rs, StringProperties properties) { - try { - for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { - if (rs.getString(i) == null) continue ; - - properties.addChild(rs.getMetaData().getColumnName(i).toLowerCase(), cleanString(rs.getString(i))); + + private IMetaObject tryConvert(IMetaObject obj) throws Exception { + if ( obj.getDbType() == null) throw new Exception(lang.getValue("errors", "emptyDbType").toString()); + + if (isSameDbType(obj) ){ + if(isSameDbVersion(obj) || obj.getDbVersionNumber() <= getDbVersionNumber()){ + return obj; } - } catch(Exception e) { - throw new ExceptionDBGitRunTime(e); + } else { + if ( checkContainsNativeFields(obj)) { + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "restore", "unsupportedTypes") + .withParams(obj.getName()) + , messageLevel + ); + } + } + + IDBConvertAdapter convertAdapter = getConvertAdapterFactory().getConvertAdapter(obj.getType().getValue()); + if (convertAdapter != null) return convertAdapter.convert(getDbType(), getDbVersion(), obj); + else { + String msg = DBGitLang.getInstance().getValue("errors", "convert", "cannotFindAdapter").withParams( + obj.getName(), obj.getDbType().toString(), obj.getDbVersion() + , getDbType().toString() + , String.valueOf(getDbVersionNumber()) + ); + throw new Exception(msg); } } - + private void createSchemaIfNeed(IMetaObject obj, Set createdSchemas) throws Exception { + String schemaName = getSchemaSynonymName(obj); + if(schemaName == null){ + ConsoleWriter.detailsPrintlnRed(DBGitLang.getInstance() + .getValue("errors", "adapter", "nullSchema") + .withParams(obj.getName()) + , messageLevel + ); + return; + } + if (!createdSchemas.contains(schemaName)) { + createSchemaIfNeed(schemaName); + createdSchemas.add(schemaName); + } + } + private void createRoleIfNeed(IMetaObject obj, Set createdRoles) throws ExceptionDBGit { +// boolean isRolesUnignored = !DBGitIgnore.getInstance().matchOne("*." + DBGitMetaType.DBGitRole.getValue()); + String ownerName = getOwnerName(obj); + + if(ownerName != null){ + if ( !createdRoles.contains(ownerName)) { + createRoleIfNeed(ownerName); + createdRoles.add(ownerName); + } + } + + } + protected boolean isExists(IMetaObject obj){ + try{ + IDBBackupAdapter backupAdapter = getBackupAdapterFactory().getBackupAdapter(AdapterFactory.createAdapter()); + return backupAdapter.isExists( + obj.getUnderlyingDbObject().getSchema(), + obj.getUnderlyingDbObject().getName() + ); + } catch (Exception ex) { + return false; + } + } + + private boolean checkContainsNativeFields(IMetaObject obj){ + if (obj instanceof MetaTable) { + MetaTable table = (MetaTable) obj; + for (DBTableField field : table.getFields().values()) { + if (field.getTypeUniversal().equals(FieldType.NATIVE)) { + return true; + } + } + } + return false; + } + private String getOwnerName(IMetaObject obj) { + if (obj instanceof MetaSql) + return ((MetaSql) obj).getSqlObject().getOwner(); + else if (obj instanceof MetaTable) + return ((MetaTable) obj).getTable().getOptions().get("owner").getData(); + else if (obj instanceof MetaSequence) + return ((MetaSequence) obj).getSequence().getOptions().get("owner").getData(); + else return null; + } private String getSchemaName(IMetaObject obj) { if (obj instanceof MetaSql) return ((MetaSql) obj).getSqlObject().getSchema(); @@ -269,17 +309,33 @@ else if (obj instanceof MetaTable) return ((MetaTable) obj).getTable().getSchema(); else if (obj instanceof MetaSequence) return ((MetaSequence) obj).getSequence().getSchema(); + else if (obj instanceof MetaTableData) + return ((MetaTableData) obj).getTable().getSchema(); else return null; } - - private String getOwnerName(IMetaObject obj) { - if (obj instanceof MetaSql) - return ((MetaSql) obj).getSqlObject().getOwner(); - else if (obj instanceof MetaTable) - return ((MetaTable) obj).getTable().getOptions().get("owner").getData(); - else if (obj instanceof MetaSequence) - return ((MetaSequence) obj).getSequence().getOptions().get("owner").getData(); - else return null; + private String getSchemaSynonymName(String schemaName) throws Exception { + String schemaSynonym = schemaName != null + ? SchemaSynonym.getInstance().getSchema(schemaName) + : null; + + return (schemaSynonym != null) + ? schemaSynonym + : schemaName; + } + private String getSchemaSynonymName(IMetaObject obj) throws Exception { + return getSchemaSynonymName(getSchemaName(obj)); + } + public Double getDbVersionNumber(){ + Matcher matcher = Pattern.compile("\\D*(\\d+)\\.(\\d+)").matcher(getDbVersion()); + matcher.find(); + Double result = Double.valueOf(matcher.group(0)+matcher.group(1)); + return result; + } + private boolean isSameDbType(IMetaObject obj){ + return obj.getDbType().equals(getDbType()); + } + private boolean isSameDbVersion(IMetaObject obj){ + return obj.getDbVersion().equals(getDbVersion()); } public void registryMappingTypes() { @@ -289,6 +345,25 @@ public void registryMappingTypes() { FactoryCellData.regMappingTypes(FieldType.NATIVE, StringData.class); FactoryCellData.regMappingTypes(FieldType.NUMBER, LongData.class); FactoryCellData.regMappingTypes(FieldType.STRING, StringData.class); + FactoryCellData.regMappingTypes(FieldType.STRING_NATIVE, StringData.class); FactoryCellData.regMappingTypes(FieldType.TEXT, TextFileData.class); } + + public String escapeNameIfNeeded(String name) { + return name; + } + + public NamedParameterPreparedStatement preparedStatement(Connection connection, String sql, Map values) throws SQLException, ExceptionDBGit { + NamedParameterPreparedStatement stmt = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(getConnection(), sql); + + for(Map.Entry entry : values.entrySet()){ + Object value = entry.getValue(); + if (value instanceof String) stmt.setString(entry.getKey(), (String) value); + else if (value instanceof Long) stmt.setLong(entry.getKey(), (Long) value); + else if (value instanceof Float) stmt.setDouble(entry.getKey(), ((Float) value).floatValue()); + else throw new ExceptionDBGit("Unsupported type of value, see stacktrace"); + } + + return stmt; + } } diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapterProxy.java b/src/main/java/ru/fusionsoft/dbgit/adapters/DBAdapterProxy.java index 8ffda91..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; @@ -227,6 +260,11 @@ public String getDbVersion() { return adapter.getDbVersion(); } + @Override + public Double getDbVersionNumber() { + return adapter.getDbVersionNumber(); + } + @Override public IFactoryDBConvertAdapter getConvertAdapterFactory() { return adapter.getConvertAdapterFactory(); @@ -253,6 +291,11 @@ public boolean isReservedWord(String word) { return adapter.isReservedWord(word); } + @Override + public String escapeNameIfNeeded(String name) { + return adapter.escapeNameIfNeeded(name); + } + @Override public DBTableData getTableDataPortion(String schema, String nameTable, int portionIndex, int tryNumber) { return adapter.getTableDataPortion(schema, nameTable, portionIndex, tryNumber); diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/DBBackupAdapter.java b/src/main/java/ru/fusionsoft/dbgit/adapters/DBBackupAdapter.java index 9ece220..10db25e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/DBBackupAdapter.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/DBBackupAdapter.java @@ -1,13 +1,12 @@ package ru.fusionsoft.dbgit.adapters; -import com.diogonunes.jcdp.color.api.Ansi; +import ru.fusionsoft.dbgit.core.DBGitIndex; import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.GitMetaDataManager; import ru.fusionsoft.dbgit.meta.*; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; -import java.sql.Timestamp; import java.text.MessageFormat; import java.util.*; import java.util.function.Function; @@ -20,6 +19,8 @@ public abstract class DBBackupAdapter implements IDBBackupAdapter { private boolean saveToSchema; protected DBGitLang lang = DBGitLang.getInstance(); + protected DBGitIndex dbGitIndex; + public void setAdapter(IDBAdapter adapter) { this.adapter = adapter; @@ -51,106 +52,125 @@ public boolean isExists(IMetaObject imo) { try { return isExists(nm.getSchema(), nm.getName()); } catch (Exception ex){ - ex.printStackTrace(); throw new RuntimeException(ex); } } - public void backupDatabase(IMapMetaObject backupObjs) throws Exception { + public void backupDatabase(IMapMetaObject updateObjs) throws Exception { - // Condition: we should not refer from backups on non-backup objects - // -> we need to backup restoring objects dependencies + // Condition: we rewrite refs on backup objects adding BACKUP$ prefix on them + // -> we need to find and add to backup list all updateObjs dependencies // Condition: old backups can refer on each other // -> we need to drop old backups of the objects + old backup dependencies // collect yet existing backups of restore objects - Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); +// Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); + dbGitIndex = DBGitIndex.getInctance(); + StatementLogging stLog = new StatementLogging(adapter.getConnection(), adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - IMapMetaObject dbObjs = GitMetaDataManager.getInstance().loadDBMetaData(false); + IMapMetaObject dbObjs = GitMetaDataManager.getInstance().loadDBMetaData(true); - IMapMetaObject backupList = new TreeMapMetaObject(dbObjs.values().stream() - .filter( x-> backupObjs.containsKey(x.getName()) ) + IMapMetaObject dbToBackup = new TreeMapMetaObject(dbObjs.values().stream() + .filter( x-> updateObjs.containsKey(x.getName()) ) .collect(Collectors.toList())); - List nonBackupList = dbObjs.values().stream() - .filter(x -> !backupObjs.containsKey(x.getName())) + List dbNotToBackup = dbObjs.values().stream() + .filter(x -> !updateObjs.containsKey(x.getName())) .collect(Collectors.toList()); - IMapMetaObject existingBackups = new TreeMapMetaObject(dbObjs.values().stream() + IMapMetaObject dbExistingBackups = new TreeMapMetaObject(dbObjs.values().stream() .filter(this::isBackupObject) .collect(Collectors.toList())); - - - ConsoleWriter.printlnColor(MessageFormat.format("Backing up {0} objects... {1} are in database:\n\t- {2}", - backupObjs.size(), backupList.size(), - String.join("\n\t- ", backupList.keySet()) - ), Ansi.FColor.MAGENTA, 1); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "backup", "tryToBackup") + .withParams( + String.valueOf(dbToBackup.size()), + String.valueOf(updateObjs.size())) + , 1 + ); // collect restore objects dependencies to satisfy all backups create needs // so dependencies will be backed up too - Map addedObjs; + Map restoreObjsDependencies; do{ - addedObjs = nonBackupList.stream().filter( nonBackup -> - nonBackup.getUnderlyingDbObject() != null - && backupList.values().stream().anyMatch( - backup -> backup.getUnderlyingDbObject().getDependencies().contains(nonBackup.getName()) + restoreObjsDependencies = dbNotToBackup.stream().filter( notToBackup -> + notToBackup.getUnderlyingDbObject() != null && + dbToBackup.values().stream().anyMatch( + toBackup -> toBackup.dependsOn(notToBackup) ) ).collect(Collectors.toMap(IMetaObject::getName, Function.identity() )); - nonBackupList.removeAll(addedObjs.values()); - backupList.putAll(addedObjs); + dbNotToBackup.removeAll(restoreObjsDependencies.values()); + dbToBackup.putAll(restoreObjsDependencies); - if(addedObjs.size() > 0) { - ConsoleWriter.printlnColor( - MessageFormat.format("- found {0} depending: {1}", addedObjs.size(), String.join(" ,", addedObjs.keySet())), - Ansi.FColor.MAGENTA, 2 + if(restoreObjsDependencies.size() > 0) { + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "backup", "dependingBackups") + .withParams( + String.valueOf(restoreObjsDependencies.size()), + String.join(" ,", restoreObjsDependencies.keySet()) + ), 2 ); } - } while (addedObjs.size() > 0); + } while (restoreObjsDependencies.size() > 0); //so we have a full backup list, let's get a drop list + if(dbToBackup.size() > 0){ + Set suspectBackupNames = dbToBackup.values().stream() + .map( x->getBackupNameMeta(x).getMetaName()) + .collect(Collectors.toSet()); - if(backupList.size() > 0){ + List dropList = new ArrayList<>(); - IMapMetaObject backupListExisting = new TreeMapMetaObject(existingBackups.values().stream() - .filter(x -> backupList.containsKey(x.getName())) + IMapMetaObject dbDroppingBackups = new TreeMapMetaObject(dbExistingBackups.values().stream() + .filter(existingBackup -> suspectBackupNames.contains(existingBackup.getName())) .collect(Collectors.toList())); - List backupListExistingDependant = existingBackups.values().stream() - .filter( x -> - !backupListExisting.containsKey(x.getName()) - || x.getUnderlyingDbObject().getDependencies().contains(x.getName()) - ) - .collect(Collectors.toList()); + List dbDroppingBackupsDeps = dbExistingBackups.values().stream() + .filter( dbBackup -> + !dbDroppingBackups.containsKey(dbBackup.getName()) + && dbDroppingBackups.values().stream().anyMatch(dbBackup::dependsOn) + ).collect(Collectors.toList()); - List dropList = new ArrayList<>(backupListExisting.values()); - dropList.addAll(backupListExistingDependant); - List dropListSorted = new SortedListMetaObject(dropList).sortFromDependant(); + dropList.addAll(dbDroppingBackups.values()); + dropList.addAll(dbDroppingBackupsDeps); + List dropListSorted = new SortedListMetaObject(dropList).sortFromDependencies(); - ConsoleWriter.printlnColor("Rewriting "+dropList.size()+" backups (with dependencies)", Ansi.FColor.MAGENTA, 1); - dropListSorted.forEach( x -> ConsoleWriter.printlnColor( "- " + x.getName(), Ansi.FColor.MAGENTA, 1)); + if(dropList.size() > 0) ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "backup", "rewritingBackups") + .withParams( + String.valueOf(dbDroppingBackups.size()), + String.valueOf(dbDroppingBackupsDeps.size()) + ), messageLevel-1 + ); //drop backups in one place for(IMetaObject imo : dropListSorted){ - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "droppingBackup").withParams(imo.getName()), 2); - + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "droppingBackup").withParams(imo.getName()), messageLevel); dropIfExists(imo, stLog); - - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } - Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); - ConsoleWriter.detailsPrintLn(MessageFormat.format("({0})", - lang.getValue("general", "add", "ms").withParams(String.valueOf(timestampAfter.getTime() - timestampBefore.getTime())) - )); + if(dbToBackup.size() > 0) ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "backup", "creatingBackups") + .withParams( + String.valueOf(dbToBackup.size()) + ), messageLevel-1 + ); + //create backups - for(IMetaObject imo : backupList.getSortedList().sortFromFree()){ + for(IMetaObject imo : dbToBackup.getSortedList().sortFromReferenced()){ backupDBObject(imo); } + + // Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); + // ConsoleWriter.detailsPrintLn(MessageFormat.format("({0})", + // lang.getValue("general", "add", "ms").withParams(String.valueOf(timestampAfter.getTime() - timestampBefore.getTime())) + // )); } } @@ -162,7 +182,8 @@ public NameMeta getBackupNameMeta(IMetaObject imo){ return new NameMeta(backupSchema, backupName, (DBGitMetaType) imo.getType()); } - public boolean isBackupObject(IMetaObject imo){ + public boolean isBackupObject(IMetaObject imo) { + if(dbGitIndex != null && dbGitIndex.getTreeItems().containsKey(imo.getName())) return false; NameMeta nm = new NameMeta(imo); return nm.getName().contains(PREFIX) || nm.getSchema().contains(PREFIX); } diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/DBRestoreAdapter.java b/src/main/java/ru/fusionsoft/dbgit/adapters/DBRestoreAdapter.java index 4b8f1ee..4680c27 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/DBRestoreAdapter.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/DBRestoreAdapter.java @@ -18,7 +18,9 @@ public abstract class DBRestoreAdapter implements IDBAdapterRestoreMetaData { protected IDBAdapter adapter = null; protected DBGitLang lang = DBGitLang.getInstance(); - + public static int messageLevel = 3; + + public void setAdapter(IDBAdapter adapter) { this.adapter = adapter; } diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/IDBAdapter.java b/src/main/java/ru/fusionsoft/dbgit/adapters/IDBAdapter.java index 502806c..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; @@ -36,6 +39,7 @@ public interface IDBAdapter { public static final int MAX_ROW_COUNT_FETCH = 10000; public static final int LIMIT_FETCH = 1; public static final int NOLIMIT_FETCH = 2; + public static final int messageLevel = 2; public void setConnection(Connection conn); @@ -142,14 +146,21 @@ 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(); public IFactoryDBConvertAdapter getConvertAdapterFactory(); public DbType getDbType(); - public String getDbVersion(); + public String getDbVersion(); + public Double getDbVersionNumber(); public void createSchemaIfNeed(String schemaName) throws ExceptionDBGit; public void createRoleIfNeed(String roleName) throws ExceptionDBGit; @@ -157,6 +168,8 @@ public interface IDBAdapter { public String getDefaultScheme() throws ExceptionDBGit; boolean isReservedWord(String word); - + + public String escapeNameIfNeeded(String name); + /*Если будет нужно - сюда можно добавить подписчиков на события*/ } diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/IDBBackupAdapter.java b/src/main/java/ru/fusionsoft/dbgit/adapters/IDBBackupAdapter.java index 0fbe1a3..dd6474b 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/IDBBackupAdapter.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/IDBBackupAdapter.java @@ -11,8 +11,9 @@ public interface IDBBackupAdapter { - public static final String PREFIX = "BACKUP$"; - + public static final String PREFIX = "BACKUP$"; + static int messageLevel = 3; + public void setAdapter(IDBAdapter adapter); public IDBAdapter getAdapter(); diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/IDBConvertAdapter.java b/src/main/java/ru/fusionsoft/dbgit/adapters/IDBConvertAdapter.java index aa11dab..ac1930e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/IDBConvertAdapter.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/IDBConvertAdapter.java @@ -7,5 +7,6 @@ import ru.fusionsoft.dbgit.meta.MetaTable; public interface IDBConvertAdapter { + public static int messageLevel = 2; public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) throws ExceptionDBGit; } diff --git a/src/main/java/ru/fusionsoft/dbgit/adapters/IFactoryDBAdapterRestoteMetaData.java b/src/main/java/ru/fusionsoft/dbgit/adapters/IFactoryDBAdapterRestoteMetaData.java index de1b8ff..a66bf9d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/adapters/IFactoryDBAdapterRestoteMetaData.java +++ b/src/main/java/ru/fusionsoft/dbgit/adapters/IFactoryDBAdapterRestoteMetaData.java @@ -6,5 +6,6 @@ import ru.fusionsoft.dbgit.meta.IDBGitMetaType; public interface IFactoryDBAdapterRestoteMetaData { + static int messageLevel = 1; public IDBAdapterRestoreMetaData getAdapterRestore(IDBGitMetaType tp, IDBAdapter adapter); } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdAdd.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdAdd.java index 854dfe4..592e14e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdAdd.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdAdd.java @@ -4,7 +4,7 @@ import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.sql.Timestamp; -import java.util.Set; +import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Options; @@ -79,21 +79,23 @@ public void execute(CommandLine cmdLine) throws Exception { DBGitConfig.getInstance().setValue("CURRENT_OBJECT", obj.getName().replace(".csv", ".tbl")); Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "add", "processingObject") + " " + obj.getName()); - ConsoleWriter.detailsPrint(getLang().getValue("general", "add", "savingToFile"), 2); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "add", "processingObject") + .withParams(obj.getName()) + , messageLevel + ); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "add", "savingToFile"), messageLevel+1); //TODO obj.saveToFile(); - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); - ConsoleWriter.detailsPrint(getLang().getValue("general", "addToGit"), 2); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "addToGit"), messageLevel+1); countSave += obj.addToGit(); - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); Long diff = timestampAfter.getTime() - timestampBefore.getTime(); - ConsoleWriter.detailsPrint(getLang().getValue("general", "time").withParams(diff.toString()), 2); - ConsoleWriter.detailsPrintLn(""); + ConsoleWriter.detailsPrint(getLang().getValue("general", "time").withParams(diff.toString())); index.addItem(obj); @@ -116,15 +118,16 @@ public void execute(CommandLine cmdLine) throws Exception { isFirstPortion = (DBGitConfig.getInstance().getInteger("core", "CURRENT_PORTION", 0) == 0); while (gmdm.loadNextPortion((MetaTable) obj)) { - ConsoleWriter.detailsPrint(getLang().getValue("general", "add", "writing").toString(), 2); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "add", "writing").toString(), messageLevel+1); try { //gmdm.getCurrent().serialize(out); Integer count = 0; - Set fields = null; + List fields = null; for (RowData rd : gmdm.getCurrent().getmapRows().values()) { if (count == 0 && isFirstPortion) { - fields = rd.getData().keySet(); + //fields = rd.getData().keySet(); + fields = gmdm.getCurrent().getFields(); csvPrinter.printRecord(fields); isFirstPortion = false; } @@ -136,7 +139,6 @@ public void execute(CommandLine cmdLine) throws Exception { } catch (Exception e) { - e.printStackTrace(); throw new ExceptionDBGit(e); } } @@ -154,8 +156,8 @@ public void execute(CommandLine cmdLine) throws Exception { index.saveDBIndex(); index.addToGit(); } else { - ConsoleWriter.printlnRed(getLang().getValue("errors", "add", "cantFindObjectInDb").withParams(nameObj)); + ConsoleWriter.printlnRed(getLang().getValue("errors", "add", "cantFindObjectInDb").withParams(nameObj), messageLevel); } - ConsoleWriter.println(getLang().getValue("general", "done")); + ConsoleWriter.println(getLang().getValue("general", "done"), messageLevel); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdCheckout.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdCheckout.java index b6538d1..5acda93 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdCheckout.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdCheckout.java @@ -1,88 +1,125 @@ -package ru.fusionsoft.dbgit.command; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLine.Builder; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; - -import ru.fusionsoft.dbgit.core.DBGit; -import ru.fusionsoft.dbgit.core.DBGitIndex; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class CmdCheckout implements IDBGitCommand { - - private Options opts = new Options(); - - public CmdCheckout() { - opts.addOption("b", false, getLang().getValue("help", "checkout-b").toString()); - opts.addOption("r", false, getLang().getValue("help", "checkout-r").toString()); - opts.addOption("u", false, getLang().getValue("help", "checkout-u").toString()); - opts.addOption("nodb", false, getLang().getValue("help", "checkout-no-db").toString()); - opts.addOption("upgrade", false, getLang().getValue("help", "checkout-u").toString()); - } - - @Override - public String getCommandName() { - return "checkout"; - } - - @Override - public String getParams() { - return " "; - } - - @Override - public String getHelperInfo() { - return getLang().getValue("help", "checkout").toString(); - } - - @Override - public Options getOptions() { - return opts; - } - - @Override - public void execute(CommandLine cmdLine) throws Exception { - - String[] args = cmdLine.getArgs(); - ConsoleWriter.setDetailedLog(cmdLine.hasOption("v")); - - if (!cmdLine.hasOption("u") && !cmdLine.hasOption("nodb")) - checkVersion(); - - if (args == null || args.length == 0) { - throw new ExceptionDBGit(getLang().getValue("errors", "checkout", "badCommand")); - } else if (args.length == 1) { - DBGit.getInstance().gitCheckout(args[0], null, cmdLine.hasOption("b")); - } else if (args.length == 2) { - DBGit.getInstance().gitCheckout(args[0], args[1], cmdLine.hasOption("b")); - } - - Builder builder = new CommandLine.Builder(); - - if (cmdLine.hasOption("u")) { - CmdDump dumpCommand = new CmdDump(); - builder.addOption(new Option("u", false, "")); - - if (cmdLine.hasOption("v")) { - builder.addOption(new Option("v", false, "")); - } - - dumpCommand.execute(builder.build()); - } else if (!cmdLine.hasOption("nodb")) { - CmdRestore restoreCommand = new CmdRestore(); - - if (cmdLine.hasOption("r")) { - builder.addOption(new Option("r", false, "")); - } - if (cmdLine.hasOption("v")) { - builder.addOption(new Option("v", false, "")); - } - - restoreCommand.execute(builder.build()); - } - - } - -} +package ru.fusionsoft.dbgit.command; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLine.Builder; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; + +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevWalk; +import ru.fusionsoft.dbgit.core.DBGit; +import ru.fusionsoft.dbgit.core.DBGitLang; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class CmdCheckout implements IDBGitCommand { + + private Options opts = new Options(); + + public CmdCheckout() { + opts.addOption("b", false, getLang().getValue("help", "checkout-b").toString()); + opts.addOption("r", false, getLang().getValue("help", "checkout-r").toString()); + opts.addOption("u", false, getLang().getValue("help", "checkout-u").toString()); + opts.addOption("nodb", false, getLang().getValue("help", "checkout-no-db").toString()); + opts.addOption("noowner", false, getLang().getValue("help", "checkout-no-owner").toString()); + opts.addOption("upgrade", false, getLang().getValue("help", "checkout-u").toString()); + opts.addOption("ls", false, getLang().getValue("help", "checkout-ls").toString()); + } + + @Override + public String getCommandName() { + return "checkout"; + } + + @Override + public String getParams() { + return " "; + } + + @Override + public String getHelperInfo() { + return getLang().getValue("help", "checkout").toString(); + } + + @Override + public Options getOptions() { + return opts; + } + + @Override + public void execute(CommandLine cmdLine) throws Exception { + + String[] args = cmdLine.getArgs(); + ConsoleWriter.setDetailedLog(cmdLine.hasOption("v")); + + Repository repo = DBGit.getInstance().getRepository(); + Ref head = repo.getAllRefs().get("HEAD"); + + if (cmdLine.hasOption("ls")){ + try(RevWalk walk = new RevWalk(repo)){ + + String branch = repo.getBranch(); + String headNumber = head.getObjectId().getName(); + String headName = head.getName(); + String message = walk.parseCommit(head.getObjectId()).getShortMessage(); + + System.out.println(DBGitLang.getInstance() + .getValue("general", "checkout", "printBranchAndCommit") + .withParams( + !branch.equals(headNumber) ? branch + ": " + headNumber : headNumber, + headName, + message + ) +// , messageLevel + ); + + } + return; + } + + if (!cmdLine.hasOption("u") && !cmdLine.hasOption("nodb")) + checkVersion(); + if (args == null || args.length == 0) { + throw new ExceptionDBGit(getLang().getValue("errors", "checkout", "badCommand")); + } else if (args.length == 1) { + DBGit.getInstance().gitCheckout(args[0], null, cmdLine.hasOption("b")); + } else if (args.length == 2) { + DBGit.getInstance().gitCheckout(args[0], args[1], cmdLine.hasOption("b")); + } + + Builder builder = new CommandLine.Builder(); + + if (cmdLine.hasOption("u")) { + CmdDump dumpCommand = new CmdDump(); + builder.addOption(new Option("u", false, "")); + + if (cmdLine.hasOption("v")) { + builder.addOption(new Option("v", false, "")); + } + + dumpCommand.execute(builder.build()); + } else if (!cmdLine.hasOption("nodb")) { + CmdRestore restoreCommand = new CmdRestore(); + + if (cmdLine.hasOption("r")) { + builder.addOption(new Option("r", false, "")); + } + if (cmdLine.hasOption("noowner")) { + builder.addOption(new Option("noowner", false, "")); + } + if (cmdLine.hasOption("v")) { + builder.addOption(new Option("v", false, "")); + } + if (cmdLine.hasOption("s")) { + Option scriptOption = new Option("s", true, ""); + scriptOption.getValuesList().add(cmdLine.getOptionValue("s")); + builder.addOption(scriptOption); + } + + restoreCommand.execute(builder.build()); + } + + } + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdClone.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdClone.java index 697407f..85a161d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdClone.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdClone.java @@ -6,10 +6,17 @@ import ru.fusionsoft.dbgit.core.DBGit; import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import java.io.File; + public class CmdClone implements IDBGitCommand { private Options opts = new Options(); - + + public CmdClone() { + opts.addOption("directory", true, "subdirectory to clone into"/*getLang + ().getValue("help", "commit-a").toString()*/); + } + @Override public String getCommandName() { return "clone"; @@ -36,6 +43,7 @@ public void execute(CommandLine cmdLine) throws Exception { String link = ""; String remote = ""; + File directory = cmdLine.hasOption("directory") ? new File(cmdLine.getOptionValue("directory")) : null; if (args.length > 2) { throw new ExceptionDBGit(getLang().getValue("errors", "paramsNumberIncorrect")); } else if (args.length == 1) { @@ -45,7 +53,7 @@ public void execute(CommandLine cmdLine) throws Exception { remote = args[1]; } - DBGit.gitClone(link, remote); + DBGit.gitClone(link, remote, directory); } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdCommit.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdCommit.java index 6c006be..e5fa306 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdCommit.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdCommit.java @@ -54,7 +54,7 @@ public void execute(CommandLine cmdLine) throws Exception { checkVersion(); - ConsoleWriter.println(getLang().getValue("general", "commit", "commiting")); + ConsoleWriter.println(getLang().getValue("general", "commit", "commiting"), messageLevel); DBGitIndex.getInctance().addLinkToGit(); DBGitIndex.getInctance().addIgnoreToGit(); DBGit.getInstance().gitCommit(cmdLine.hasOption("a"), msg, filePath); diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdDump.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdDump.java index 16a0b1d..caec41b 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdDump.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdDump.java @@ -1,108 +1,120 @@ -package ru.fusionsoft.dbgit.command; - -import java.sql.Timestamp; -import java.util.Map; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.Options; - -import ru.fusionsoft.dbgit.core.DBGit; -import ru.fusionsoft.dbgit.core.DBGitIndex; -import ru.fusionsoft.dbgit.core.DBGitPath; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.GitMetaDataManager; -import ru.fusionsoft.dbgit.meta.IMapMetaObject; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class CmdDump implements IDBGitCommand { - private Options opts = new Options(); - - public CmdDump() { - opts.addOption("a", false, getLang().getValue("help", "dump-a").toString()); - opts.addOption("f", false, getLang().getValue("help", "dump-f").toString()); - opts.addOption("u", false, getLang().getValue("help", "dump-u").toString()); - } - - public String getCommandName() { - return "dump"; - } - - public String getParams() { - return ""; - } - - public String getHelperInfo() { - return getLang().getValue("help", "dump").toString(); - } - - public Options getOptions() { - return opts; - } - @Override - public void execute(CommandLine cmdLine) throws Exception { - Boolean isAddToGit = cmdLine.hasOption('a'); - Boolean isAllDump = cmdLine.hasOption('f'); - - ConsoleWriter.setDetailedLog(cmdLine.hasOption("v")); - - GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); - - DBGitIndex index = DBGitIndex.getInctance(); - - if (!cmdLine.hasOption("u")) - checkVersion(); - - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "dump", "checking")); - - IMapMetaObject fileObjs = gmdm.loadFileMetaDataForce(); - - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "dump", "dumping")); - - for (IMetaObject obj : fileObjs.values()) { - Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "dump", "processing").withParams(obj.getName())); - String hash = obj.getHash(); - ConsoleWriter.detailsPrint(getLang().getValue("general", "dump", "hash") + ": " + hash + "\n", 2); - - ConsoleWriter.detailsPrint(getLang().getValue("general", "dump", "loading") + "\n", 2); - if (!gmdm.loadFromDB(obj)) { - ConsoleWriter.println(getLang().getValue("general", "dump", "cantFindInDb").withParams(obj.getName())); - continue; - } - ConsoleWriter.detailsPrint(getLang().getValue("general", "dump", "dbHash") + ": " + obj.getHash() + "\n", 2); - - if (isAllDump || !obj.getHash().equals(hash)) { - if (!obj.getHash().equals(hash)) - ConsoleWriter.detailsPrint(getLang().getValue("general", "dump", "hashesDifferent"), 2); - else - ConsoleWriter.detailsPrint(getLang().getValue("general", "dump", "fSwitchFound"), 2); - //сохранили файл если хеш разный - obj.saveToFile(); - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); - ConsoleWriter.detailsPrint(getLang().getValue("general", "dump", "addToIndex"), 2); - index.addItem(obj); - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); - - if (isAddToGit) { - ConsoleWriter.detailsPrint(getLang().getValue("general", "addToGit"), 2); - obj.addToGit(); - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); - } - } else { - ConsoleWriter.detailsPrint(getLang().getValue("general", "dump", "hashesMatch") + "\n", 2); - } - Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); - Long diff = timestampAfter.getTime() - timestampBefore.getTime(); - ConsoleWriter.detailsPrint(getLang().getValue("general", "time").withParams(diff.toString()), 2); - ConsoleWriter.detailsPrintLn(""); - } - - index.saveDBIndex(); - if (isAddToGit) { - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "addToGit")); - index.addToGit(); - } - ConsoleWriter.println(getLang().getValue("general", "done")); - } -} +package ru.fusionsoft.dbgit.command; + +import java.sql.Timestamp; +import java.util.Map; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; + +import ru.fusionsoft.dbgit.core.*; +import ru.fusionsoft.dbgit.meta.IMapMetaObject; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class CmdDump implements IDBGitCommand { + private Options opts = new Options(); + + public CmdDump() { + opts.addOption("a", false, getLang().getValue("help", "dump-a").toString()); + opts.addOption("f", false, getLang().getValue("help", "dump-f").toString()); + opts.addOption("u", false, getLang().getValue("help", "dump-u").toString()); + } + + public String getCommandName() { + return "dump"; + } + + public String getParams() { + return ""; + } + + public String getHelperInfo() { + return getLang().getValue("help", "dump").toString(); + } + + public Options getOptions() { + return opts; + } + @Override + public void execute(CommandLine cmdLine) throws Exception { + Boolean isAddToGit = cmdLine.hasOption('a'); + Boolean isAllDump = cmdLine.hasOption('f'); + + ConsoleWriter.setDetailedLog(cmdLine.hasOption("v")); + + GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); + + DBGitIndex index = DBGitIndex.getInctance(); + + if (!cmdLine.hasOption("u")) + checkVersion(); + + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "checking"), messageLevel); + + IMapMetaObject fileObjs = gmdm.loadFileMetaDataForce(); + + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "dumping"), messageLevel); + + for (IMetaObject obj : fileObjs.values()) { + Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "processing") + .withParams(obj.getName()) + , messageLevel + ); + String hash = obj.getHash(); + + ConsoleWriter.detailsPrintln(DBGitLang.getInstance() + .getValue("general", "dump", "hash") + .withParams(hash) + , messageLevel+1 + ); + + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "loading"), messageLevel+1); + if (!gmdm.loadFromDB(obj)) { + ConsoleWriter.println(getLang().getValue("general", "dump", "cantFindInDb") + .withParams(obj.getName()) + , messageLevel + ); + continue; + } + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "dbHash") + .withParams(obj.getHash()), messageLevel+1 + ); + + if (isAllDump || !obj.getHash().equals(hash)) { + if (!obj.getHash().equals(hash)) + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "hashesDifferent") + , messageLevel+1 + ); + else + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "fSwitchFound") + , messageLevel+1 + ); + //сохранили файл если хеш разный + obj.saveToFile(); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "addToIndex"), messageLevel+1); + index.addItem(obj); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); + + if (isAddToGit) { + ConsoleWriter.detailsPrintln(getLang().getValue("general", "addToGit"), messageLevel+1); + obj.addToGit(); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); + } + } else { + ConsoleWriter.detailsPrintln(getLang().getValue("general", "dump", "hashesMatch"), messageLevel+1); + } + Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); + Long diff = timestampAfter.getTime() - timestampBefore.getTime(); + ConsoleWriter.detailsPrint(getLang().getValue("general", "time").withParams(diff.toString())); + } + + index.saveDBIndex(); + if (isAddToGit) { + ConsoleWriter.detailsPrintln(getLang().getValue("general", "addToGit"), messageLevel+1); + index.addToGit(); + } + ConsoleWriter.println(getLang().getValue("general", "done"), messageLevel); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdFetch.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdFetch.java index 2779dc5..f7cf5c0 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdFetch.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdFetch.java @@ -37,7 +37,7 @@ public void execute(CommandLine cmdLine) throws Exception { String[] args = cmdLine.getArgs(); String remote = ""; - ConsoleWriter.println(getLang().getValue("general", "fetch", "fetching")); + ConsoleWriter.println(getLang().getValue("general", "fetch", "fetching"), messageLevel); if (args.length == 1) { remote = args[0]; diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdHelp.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdHelp.java index fedfc7d..e146cf4 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdHelp.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdHelp.java @@ -31,7 +31,7 @@ public Options getOptions() { } @Override public void execute(CommandLine cmdLine) throws Exception { - ConsoleWriter.println(getLang().getValue("help", "common")); + ConsoleWriter.println(getLang().getValue("help", "common"), messageLevel); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdInit.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdInit.java index 8aace6b..f57e10c 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdInit.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdInit.java @@ -42,7 +42,6 @@ public void execute(CommandLine cmdLine) throws Exception { } DBGit.gitInit(dir); - } } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdLink.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdLink.java index 02b7900..f4f343a 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdLink.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdLink.java @@ -21,6 +21,7 @@ public class CmdLink implements IDBGitCommand { public CmdLink() { opts.addOption("d", false, getLang().getValue("help", "link-d").toString()); + opts.addOption("ls", false, getLang().getValue("help", "link-ls").toString()); } public String getCommandName() { @@ -43,21 +44,27 @@ public Options getOptions() { @Override public void execute(CommandLine cmdLine) throws Exception { + DBConnection conn = DBConnection.getInstance(false); + if(cmdLine.hasOption("ls")) { +// ConsoleWriter.printlnGreen(DBConnection.loadFileDBLink(new Properties()), messageLevel); + System.out.println(DBConnection.loadFileDBLink(new Properties())); + return; + } + + String[] args = cmdLine.getArgs(); - if(args == null || args.length == 0) { throw new ExceptionDBGit(getLang().getValue("errors", "link", "emptyLink")); } - + String url = args[0]; Properties props = CreateProperties(Arrays.copyOfRange(args, 1, args.length)); - - DBConnection conn = DBConnection.getInstance(false); - if(conn.testingConnection(url, props)) { - DBConnection.createFileDBLink(url, props, cmdLine.hasOption("d")); - DBGitPath.createDefaultDbignore(DBGitPath.getFullPath(), url, props); - } + DBConnection.createFileDBLink(url, props, cmdLine.hasOption("d")); + DBGitPath.createDefaultDbignore(DBGitPath.getFullPath(), url, props); + if(!conn.testingConnection(url, props)) { + throw new ExceptionDBGit("Db connection link seems not working"); + } } public Properties CreateProperties(String[] args) { diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdRestore.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdRestore.java index 121ad2c..07eb480 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdRestore.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdRestore.java @@ -2,11 +2,14 @@ import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import java.nio.file.Files; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Map; +import java.util.stream.Collectors; -import com.google.common.collect.Lists; +import com.diogonunes.jcdp.color.api.Ansi; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Options; @@ -43,107 +46,143 @@ public Options getOptions() { @Override public void execute(CommandLine cmdLine) throws Exception { + IDBAdapter adapter = null; + File autoScriptFile = createScriptFile(); + FileOutputStream scriptOutputStream = new FileOutputStream(autoScriptFile); + GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); + + ConsoleWriter.setDetailedLog(cmdLine.hasOption("v")); + ConsoleWriter.println(getLang().getValue("general", "restore", "do"), 0); + + boolean toMakeChanges = cmdLine.hasOption("r"); + boolean toMakeBackup = DBGitConfig.getInstance().getBoolean("core", "TO_MAKE_BACKUP", true); + // from cmdLine to temporary config bypass + // can be used as other config data by restore adapters + DBGitConfig.getInstance().setToIgnoreOnwer(cmdLine.hasOption("noowner")); try { - AdapterFactory.createAdapter(); + adapter = AdapterFactory.createAdapter(); + adapter.setDumpSqlCommand(scriptOutputStream, toMakeChanges); } catch (NullPointerException e) { - ConsoleWriter.println(getLang().getValue("errors", "restore", "cantConnect")); + ConsoleWriter.println(getLang().getValue("errors", "restore", "cantConnect"), messageLevel); System.exit(0); } - GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); + IMapMetaObject dbObjs = gmdm.loadDBMetaData(); IMapMetaObject fileObjs = gmdm.loadFileMetaData(); IMapMetaObject updateObjs = new TreeMapMetaObject(); IMapMetaObject deleteObjs = new TreeMapMetaObject(); - SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); - File scriptFile = new File(DBGitPath.getScriptsPath() + "script-" + format.format(new Date()) + ".sql"); - - //Console output - ConsoleWriter.setDetailedLog(cmdLine.hasOption("v")); - - boolean toMakeBackup = DBGitConfig.getInstance().getBoolean("core", "TO_MAKE_BACKUP", true); - if(toMakeBackup) ConsoleWriter.println(getLang().getValue("general", "restore", "willMakeBackup").toString()); - - if (cmdLine.hasOption("r")) { ConsoleWriter.println(getLang().getValue("general", "restore", "toMakeChanges").toString()); } - else { ConsoleWriter.println(getLang().getValue("general", "restore", "notMakeChanges").withParams(scriptFile.getAbsolutePath())); } - - //File output - FileOutputStream fop = null; - FileOutputStream scriptOutputStream = null; - - DBGitPath.createScriptsDir(); - if (!scriptFile.exists()) { scriptFile.createNewFile(); } - scriptOutputStream = new FileOutputStream(scriptFile); - - IDBAdapter adapter = AdapterFactory.createAdapter(); - adapter.setDumpSqlCommand(scriptOutputStream, cmdLine.hasOption("r")); + if (toMakeBackup) { ConsoleWriter.printlnColor(getLang().getValue("general", "restore", "willMakeBackup").toString(), Ansi.FColor.GREEN, messageLevel+1); } + else { ConsoleWriter.printlnColor(getLang().getValue("general", "restore", "wontMakeBackup").toString(), Ansi.FColor.GREEN, messageLevel+1); } + if (toMakeChanges) { ConsoleWriter.printlnColor(getLang().getValue("general", "restore", "toMakeChanges").toString(), Ansi.FColor.GREEN, messageLevel+1); } + else { ConsoleWriter.printlnColor(getLang().getValue("general", "restore", "notMakeChanges").withParams(autoScriptFile.getAbsolutePath()), Ansi.FColor.GREEN, messageLevel+1); } //delete that not present in HEAD try { DBGitIndex index = DBGitIndex.getInctance(); DBGitIgnore ignore = DBGitIgnore.getInstance(); - ConsoleWriter.println(getLang().getValue("general", "restore", "seekingToRemove")); - for (ItemIndex item : Lists.newArrayList(index.getTreeItems().values())) { - if (ignore.matchOne(item.getName())) continue; - if (item.getIsDelete()) { - if( !dbObjs.containsKey(item.getName()) ) { - ConsoleWriter.println(getLang().getValue("general", "restore", "notExists").withParams(item.getName())); + ConsoleWriter.println(getLang().getValue("general", "restore", "seekingToRemove"),1); +// ConsoleWriter.print(getLang().getValue("general", "restore", "toRemove")); + + for ( ItemIndex item : index.getTreeItems().values() ) { + if ( ignore.matchOne(item.getName()) ) continue; + + if ( item.getIsDelete() ) { + + if ( !dbObjs.containsKey(item.getName()) ) { + ConsoleWriter.println(getLang().getValue("general", "restore", "notExists").withParams(item.getName()), 2); index.removeItem(item.getName()); } else { + try { IMetaObject obj = MetaObjectFactory.createMetaObject(item.getName()); gmdm.loadFromDB(obj); if (item.getHash().equals(obj.getHash())) { deleteObjs.put(obj); - if (deleteObjs.size() == 1) ConsoleWriter.println(getLang().getValue("general", "restore", "toRemove")); - ConsoleWriter.println(" " + obj.getName()); + + ConsoleWriter.println(getLang().getValue("general", "restore", "objectToRemove").withParams(obj.getName()), 2); } } catch(ExceptionDBGit e) { - LoggerUtil.getGlobalLogger().error(getLang().getValue("errors", "restore", "cantConnect") + ": " + item.getName(), e); + throw e; + //LoggerUtil.getGlobalLogger().error(getLang().getValue("errors", "restore", "cantConnect") + ": " + item.getName(), e); } } } } - if (deleteObjs.size() == 0){ - ConsoleWriter.println(getLang().getValue("general", "restore", "nothingToRemove")); - } else { - if (cmdLine.hasOption("r")) ConsoleWriter.println(getLang().getValue("general", "restore", "removing")); - gmdm.deleteDataBase(deleteObjs, true); - } + if (deleteObjs.size() == 0) ConsoleWriter.println(getLang().getValue("general", "restore", "nothingToRemove").toString(), 2); + - ConsoleWriter.println(getLang().getValue("general", "restore", "seekingToRestore")); + ConsoleWriter.println(getLang().getValue("general", "restore", "seekingToRestore"),1); for (IMetaObject obj : fileObjs.values()) { - Boolean isRestore = false; - try { - IMetaObject dbObj = IMetaObject.create(obj.getName()); - gmdm.loadFromDB(dbObj); - isRestore = !dbObj.getHash().equals(obj.getHash()); - } catch (ExceptionDBGit e) { - isRestore = true; - e.printStackTrace(); - } catch (ExceptionDBGitRunTime e) { - isRestore = true; - e.printStackTrace(); - } - if (isRestore) { - //запомнили файл если хеш разный или объекта нет - updateObjs.put(obj); - if (updateObjs.size() == 1) ConsoleWriter.println(getLang().getValue("general", "restore", "toRestore")); - ConsoleWriter.println(" " + obj.getName()); + //запомнили файл если хеш разный или объекта нет + if (checkNeedsRestore(obj)) { + updateObjs.put(obj); +// if (updateObjs.size() == 1){ +// ConsoleWriter.print(getLang().getValue("general", "restore", "toRestore")); +// } + ConsoleWriter.println(obj.getName(), 2); } } - if (updateObjs.size() == 0){ - ConsoleWriter.println(getLang().getValue("general", "restore", "nothingToRestore")); + ConsoleWriter.println(getLang().getValue("general", "restore", "nothingToRestore").toString(), 2); + } + + // to fix pk constraint re-creation error + // collect other file objects that depend on update objects + // to re-create their fk constraints too, so we: + + // 0. enrich update list with fk-dependant objects from database + // 1. drop all of constraints + // 2. re-create all constraints in default sorted order + + // # steps 1,2 are in GitMetaDataManager::restoreDatabase + + ConsoleWriter.println(getLang().getValue("general", "restore", "seekingToRestoreAdditional"),1); + Map affectedTables = new TreeMapMetaObject(); + Map foundTables = new TreeMapMetaObject(); + do { + foundTables = + dbObjs.values().stream() + .filter(excluded -> { + return excluded instanceof MetaTable + && ! updateObjs.containsKey(excluded.getName()) + && updateObjs.values().stream().anyMatch(excluded::dependsOn); + }) + .collect(Collectors.toMap(IMetaObject::getName, val -> val)); + affectedTables.putAll(foundTables); + updateObjs.putAll(foundTables); + } while (!foundTables.isEmpty()); + + if(affectedTables.isEmpty()){ + ConsoleWriter.println(getLang().getValue("general", "restore", "nothingToRestoreAdditional"), 2); + } else { + affectedTables.forEach((k,v)->ConsoleWriter.println(k, 2)); } - if (cmdLine.hasOption("r")) { - ConsoleWriter.println(getLang().getValue("general", "restore", "restoring")); + + + + if(toMakeBackup && toMakeChanges) { + IMapMetaObject backupObjs = new TreeMapMetaObject(); + backupObjs.putAll(deleteObjs); + backupObjs.putAll(updateObjs); + adapter.getBackupAdapterFactory().getBackupAdapter(adapter).backupDatabase(backupObjs); + } + + if (deleteObjs.size() != 0){ + if (toMakeChanges) ConsoleWriter.println(getLang().getValue("general", "restore", "removing"),1); + gmdm.deleteDataBase(deleteObjs, true); + } + + + if (toMakeChanges) { + ConsoleWriter.println(getLang().getValue("general", "restore", "restoring"),1); } gmdm.restoreDataBase(updateObjs); + } finally { if (scriptOutputStream != null) { scriptOutputStream.flush(); @@ -151,17 +190,39 @@ public void execute(CommandLine cmdLine) throws Exception { } if (cmdLine.hasOption("s")) { String scriptName = cmdLine.getOptionValue("s"); - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "restore", "scriptWillSaveTo").withParams(scriptName)); - File file = new File(scriptName); + if (!file.exists()) { - Files.copy(scriptFile.toPath(), file.toPath()); - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "restore", "created").withParams(scriptName)); + ConsoleWriter.println(getLang().getValue("general", "restore", "scriptWillSaveTo").withParams(scriptName),1); + Files.copy(autoScriptFile.toPath(), file.toPath()); + } else { + ConsoleWriter.println(getLang().getValue("errors", "restore", "fileAlreadyExists").withParams(scriptName),1); } } } - ConsoleWriter.println(getLang().getValue("general", "done")); + ConsoleWriter.println(getLang().getValue("general", "done"), messageLevel); } + private boolean checkNeedsRestore(IMetaObject obj){ + boolean isRestore = false; + try { + IMetaObject dbObj = IMetaObject.create(obj.getName()); + final boolean exists = GitMetaDataManager.getInstance().loadFromDB(dbObj); + isRestore = !exists || !dbObj.getHash().equals(obj.getHash()); + } catch (ExceptionDBGit e) { + throw new ExceptionDBGitRunTime(e); +// isRestore = true; +// e.printStackTrace(); + } + return isRestore; + } + private File createScriptFile() throws ExceptionDBGit, IOException { + DBGitPath.createScriptsDir(); + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); + File scriptFile = new File(DBGitPath.getScriptsPath() + "script-" + format.format(new Date()) + ".sql"); +// System.out.println(scriptFile.getAbsolutePath()); + if (!scriptFile.exists()) { scriptFile.createNewFile(); } + return scriptFile; + } } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdRm.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdRm.java index 6089d45..3855497 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdRm.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdRm.java @@ -54,7 +54,7 @@ public void execute(CommandLine cmdLine) throws Exception { DBGitIndex index = DBGitIndex.getInctance(); - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "rm", "checking")); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "rm", "checking"), messageLevel+1); GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); IMapMetaObject dbObjs = gmdm.loadFileMetaDataForce(); @@ -64,12 +64,15 @@ public void execute(CommandLine cmdLine) throws Exception { Integer countDelete = 0; - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "rm", "deleting")); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "rm", "deleting"), messageLevel+1); for (ItemIndex idxItem : index.getTreeItems().values()) { if (maskAdd.match(idxItem.getName())) { Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); - ConsoleWriter.detailsPrintLn(getLang().getValue("general", "rm", "processing").withParams(idxItem.getName())); - ConsoleWriter.detailsPrint(getLang().getValue("general", "rm", "removingFromGit"), 2); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "rm", "processing") + .withParams(idxItem.getName()) + , messageLevel+1 + ); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "rm", "removingFromGit"), messageLevel+2); IMetaObject metaObject = dbObjs.get(idxItem.getName()); if(metaObject != null){ @@ -80,39 +83,46 @@ public void execute(CommandLine cmdLine) throws Exception { metaObject = IMetaObject.create(idxItem.getName()); } - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); - ConsoleWriter.detailsPrint(getLang().getValue("general", "rm", "markingToDelete") + " ... ", 2); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "rm", "markingToDelete") + " ... ", messageLevel+2); index.markItemToDelete(metaObject); - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); Long diff = timestampAfter.getTime() - timestampBefore.getTime(); - ConsoleWriter.detailsPrint(getLang().getValue("general", "time").withParams(diff.toString()), 2); - ConsoleWriter.detailsPrintLn(""); + ConsoleWriter.detailsPrint(getLang().getValue("general", "time").withParams(diff.toString())); } } if (forgetImmediately) { - ConsoleWriter.detailsPrint(getLang().getValue("general", "rm", "removingFromIndex"), 2); - index.getTreeItems().values().stream().filter(ItemIndex::getIsDelete).collect(Collectors.toList()).forEach(x->index.getTreeItems().remove(x.getName())); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "rm", "removingFromIndex"), messageLevel+1); + index.getTreeItems().values() + .stream() + .filter(ItemIndex::getIsDelete) + .collect(Collectors.toList()) + .forEach( + x->index.getTreeItems() + .remove(x.getName()) + ); + index.saveDBIndex(); index.addToGit(); - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); } if (cmdLine.hasOption("db")) { - ConsoleWriter.detailsPrint(getLang().getValue("general", "rm", "removingFromDb"), 2); + ConsoleWriter.detailsPrintln(getLang().getValue("general", "rm", "removingFromDb"), messageLevel+1); gmdm.deleteDataBase(deleteObjs, true); - ConsoleWriter.detailsPrintlnGreen(getLang().getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(getLang().getValue("general", "ok")); } if (countDelete > 0) { index.saveDBIndex(); index.addToGit(); } else { - ConsoleWriter.printlnRed(getLang().getValue("errors", "rm", "cantFindFile").withParams(nameObj)); + ConsoleWriter.printlnRed(getLang().getValue("errors", "rm", "cantFindFile").withParams(nameObj), messageLevel+1); } - ConsoleWriter.println(getLang().getValue("general", "done")); + ConsoleWriter.println(getLang().getValue("general", "done"), messageLevel); } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdStatus.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdStatus.java index b3648e0..a5feb01 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdStatus.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdStatus.java @@ -7,14 +7,9 @@ import com.diogonunes.jcdp.color.api.Ansi.FColor; -import ru.fusionsoft.dbgit.core.DBGit; -import ru.fusionsoft.dbgit.core.DBGitIndex; -import ru.fusionsoft.dbgit.core.DBGitPath; -import ru.fusionsoft.dbgit.core.GitMetaDataManager; -import ru.fusionsoft.dbgit.core.SchemaSynonym; +import ru.fusionsoft.dbgit.core.*; import ru.fusionsoft.dbgit.meta.IMapMetaObject; import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaTableData; import ru.fusionsoft.dbgit.meta.TreeMapMetaObject; import ru.fusionsoft.dbgit.utils.ConsoleWriter; @@ -56,23 +51,23 @@ public void execute(CommandLine cmdLine) throws Exception { DBGit dbGit = DBGit.getInstance(); boolean hasConflicts = DBGitIndex.getInctance().hasConflicts(); String repoVersion = DBGitIndex.getInctance().getRepoVersion(); - ConsoleWriter.println(getLang().getValue("general", "status", "repVersion").withParams(repoVersion)); - ConsoleWriter.println(getLang().getValue("general", "status", "dbgitVersion").withParams(DBGitIndex.VERSION)); - + ConsoleWriter.println(getLang().getValue("general", "status", "repVersion").withParams(repoVersion), messageLevel); + ConsoleWriter.println(getLang().getValue("general", "status", "dbgitVersion").withParams(DBGitIndex.VERSION), messageLevel); + if (!DBGitIndex.getInctance().isCorrectVersion()) - ConsoleWriter.println(getLang().getValue("general", "status", "differentVersions")); + ConsoleWriter.println(getLang().getValue("general", "status", "differentVersions"), messageLevel); if (hasConflicts) { - ConsoleWriter.println(getLang().getValue("general", "status", "conflicts")); + ConsoleWriter.println(getLang().getValue("general", "status", "conflicts"), messageLevel); } SchemaSynonym ss = SchemaSynonym.getInstance(); if (ss.getCountSynonym() > 0) { - ConsoleWriter.printlnGreen(getLang().getValue("general", "status", "usedSynonyms")); - ConsoleWriter.printlnGreen(getLang().getValue("general", "status", "synSchema")); + ConsoleWriter.printlnGreen(getLang().getValue("general", "status", "usedSynonyms"), messageLevel); + ConsoleWriter.printlnGreen(getLang().getValue("general", "status", "synSchema"), messageLevel); for (Entry el : ss.getMapSchema().entrySet()) { - ConsoleWriter.println(el.getKey() + " - " + el.getValue()); + ConsoleWriter.println(el.getKey() + " - " + el.getValue(), messageLevel+1); } } @@ -107,40 +102,40 @@ public void execute(CommandLine cmdLine) throws Exception { addedObjs.put(fileObjs.get(name)); } - ConsoleWriter.println(getLang().getValue("general", "status", "changesToCommit")); + ConsoleWriter.println(getLang().getValue("general", "status", "changesToCommit"), messageLevel); for(IMetaObject obj : addedObjs.values()) { - printObect(obj, FColor.GREEN, 1); + printObect(obj, FColor.GREEN, messageLevel+1); } - ConsoleWriter.println(" "); + ConsoleWriter.printLineBreak(); - ConsoleWriter.println(getLang().getValue("general", "status", "notStaged")); + ConsoleWriter.println(getLang().getValue("general", "status", "notStaged"), messageLevel); for(IMetaObject obj : changeObjs.values()) { printObect(obj, FColor.RED, 1); } - ConsoleWriter.println(" "); - + ConsoleWriter.printLineBreak(); + - ConsoleWriter.println(getLang().getValue("general", "status", "untracked")); + ConsoleWriter.println(getLang().getValue("general", "status", "untracked"), messageLevel); for (String name : dbObjs.keySet()) { if (!fileObjs.containsKey(name)) { - ConsoleWriter.println(name, 1); + ConsoleWriter.println(name, messageLevel+1); } } - ConsoleWriter.println(" "); + ConsoleWriter.printLineBreak(); - ConsoleWriter.println(getLang().getValue("general", "status", "localNotStaged")); + ConsoleWriter.println(getLang().getValue("general", "status", "localNotStaged"), messageLevel); for (String modified : DBGit.getInstance().getModifiedFiles()) { - ConsoleWriter.printlnColor(modified, FColor.RED, 1); + ConsoleWriter.printlnColor(modified, FColor.RED, messageLevel+1); } - ConsoleWriter.println(" "); + ConsoleWriter.printLineBreak(); - ConsoleWriter.println(getLang().getValue("general", "status", "localToCommit")); + ConsoleWriter.println(getLang().getValue("general", "status", "localToCommit"), messageLevel); for (String modified : DBGit.getInstance().getChanged()) { - ConsoleWriter.printlnColor(modified, FColor.GREEN, 1); + ConsoleWriter.printlnColor(modified, FColor.GREEN , messageLevel+1); } - ConsoleWriter.println(" "); + ConsoleWriter.printLineBreak(); } public void printObect(IMetaObject obj, FColor color, Integer level) { diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdSynonymSchema.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdSynonymSchema.java index e1e41a9..b4febfe 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdSynonymSchema.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdSynonymSchema.java @@ -39,9 +39,9 @@ public void execute(CommandLine cmdLine) throws Exception { Boolean isShow = cmdLine.hasOption('s'); if (isShow) { - ConsoleWriter.printlnGreen(getLang().getValue("general", "status", "synSchema")); + ConsoleWriter.printlnGreen(getLang().getValue("general", "status", "synSchema"), messageLevel); for (Entry el : ss.getMapSchema().entrySet()) { - ConsoleWriter.println(el.getKey() + " - " + el.getValue()); + ConsoleWriter.println(el.getKey() + " - " + el.getValue(), messageLevel+1); } return ; } @@ -66,6 +66,6 @@ public void execute(CommandLine cmdLine) throws Exception { } ss.saveFile(); - ConsoleWriter.println(getLang().getValue("general", "done")); + ConsoleWriter.println(getLang().getValue("general", "done"), messageLevel); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/CmdValid.java b/src/main/java/ru/fusionsoft/dbgit/command/CmdValid.java index 7e7c241..c5ba535 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/CmdValid.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/CmdValid.java @@ -43,9 +43,9 @@ public void execute(CommandLine cmdLine) throws Exception { //возможно за списком файлов нужно будет сходить в гит индекс try { Map fileObjs = gmdm.loadFileMetaData(); - ConsoleWriter.printlnGreen(getLang().getValue("general", "valid", "allOk")); + ConsoleWriter.printlnGreen(getLang().getValue("general", "valid", "allOk"), messageLevel); } catch (Exception e) { - ConsoleWriter.printlnRed(e.getMessage()); + ConsoleWriter.printlnRed(e.getMessage(), messageLevel); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/command/IDBGitCommand.java b/src/main/java/ru/fusionsoft/dbgit/command/IDBGitCommand.java index 0554dff..d7e2187 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/IDBGitCommand.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/IDBGitCommand.java @@ -15,6 +15,8 @@ * */ public interface IDBGitCommand { + public static int messageLevel = 0; + public void execute(CommandLine cmdLine) throws Exception; public String getCommandName(); diff --git a/src/main/java/ru/fusionsoft/dbgit/command/RequestCmd.java b/src/main/java/ru/fusionsoft/dbgit/command/RequestCmd.java index ac12e4f..d693219 100644 --- a/src/main/java/ru/fusionsoft/dbgit/command/RequestCmd.java +++ b/src/main/java/ru/fusionsoft/dbgit/command/RequestCmd.java @@ -96,11 +96,9 @@ protected static Options addHelpOptions(Options opts) throws ExceptionDBGit { if (opts.getOption("h") == null) { opts.addOption("h", false, DBGitLang.getInstance().getValue("help", "h").toString()); } - if (opts.getOption("v") == null) { opts.addOption("v", false, DBGitLang.getInstance().getValue("help", "v").toString()); } - return opts; } @@ -108,11 +106,8 @@ public void printHelpAboutCommand(String command) throws Exception { if (!commands.containsKey(command)) { throw new ExceptionCmdNotFound(DBGitLang.getInstance().getValue("errors", "commandNotFound").withParams(command)); } - IDBGitCommand cmdObj = commands.get(command); - HelpFormatter helpFormatter = new HelpFormatter(); - helpFormatter.printHelp( "dbgit "+command+" "+cmdObj.getParams(), cmdObj.getHelperInfo(), @@ -123,62 +118,66 @@ public void printHelpAboutCommand(String command) throws Exception { } - public static void main( String[] args ) throws Exception - { - ConsoleWriter.println( "dbgit utils - Hello!"); - - //configureLogback(); - - try { - CommandLineParser clParse = new DefaultParser(); - Options opts = new Options(); - opts.addOption("a", false, "Option A"); - opts.addOption("b", true, "Option B"); - opts.addOption("c", false, "Option C"); - opts.addOption("f", false, "Flag F"); - - addHelpOptions(opts); - - CommandLine cmdLine = clParse.parse(opts, args); - System.out.println(cmdLine.getArgs().length); - - System.out.println(cmdLine.hasOption('a')); - System.out.println(cmdLine.hasOption('c')); - - - HelpFormatter helpFormatter = new HelpFormatter(); - //helpFormatter.setArgName("argument"); - helpFormatter.printHelp("this help", "header", opts, "footer", true); - - - /* - printHelp( - opts, // опции по которым составляем help - 80, // ширина строки вывода - "Options", // строка предшествующая выводу - "-- HELP --", // строка следующая за выводом - 3, // число пробелов перед выводом опции - 5, // число пробелов перед выводом опцисания опции - true, // выводить ли в строке usage список команд - System.out // куда производить вывод - ); - - */ - - for (int i = 0; i < cmdLine.getArgs().length; i++) { - System.out.println(cmdLine.getArgs()[i]); - } - - - - ConsoleWriter.println( "execute command success!"); - } catch (Exception e) { - ConsoleWriter.printlnRed("Error execute dbgit: "+e.getMessage()); - LoggerUtil.getGlobalLogger().error(e.getMessage(), e); - } - - } - - - +// public static void main( String[] args ) throws Exception +// { +// ConsoleWriter.println( "dbgit utils - Hello!", 0); +// +// //configureLogback(); +// +// try { +// CommandLineParser clParse = new DefaultParser(); +// Options opts = new Options(); +// opts.addOption("a", false, "Option A"); +// opts.addOption("b", true, "Option B"); +// opts.addOption("c", false, "Option C"); +// opts.addOption("f", false, "Flag F"); +// +// addHelpOptions(opts); +// +// CommandLine cmdLine = clParse.parse(opts, args); +// System.out.println(cmdLine.getArgs().length); +// +// System.out.println(cmdLine.hasOption('a')); +// System.out.println(cmdLine.hasOption('c')); +// +// +// HelpFormatter helpFormatter = new HelpFormatter(); +// //helpFormatter.setArgName("argument"); +// helpFormatter.printHelp("this help", "header", opts, "footer", true); +// +// +// /* +// printHelp( +// opts, // опции по которым составляем help +// 80, // ширина строки вывода +// "Options", // строка предшествующая выводу +// "-- HELP --", // строка следующая за выводом +// 3, // число пробелов перед выводом опции +// 5, // число пробелов перед выводом опцисания опции +// true, // выводить ли в строке usage список команд +// System.out // куда производить вывод +// ); +// +// */ +// +// for (int i = 0; i < cmdLine.getArgs().length; i++) { +// System.out.println(cmdLine.getArgs()[i]); +// } +// +// +// +// ConsoleWriter.println(DBGitLang.getInstance() +// .getValue("general", "commandSuccess") +// , 0 +// ); +// } catch (Exception e) { +// ConsoleWriter.printlnRed(DBGitLang.getInstance() +// .getValue("errors", "cmdException") +// .withParams(e.getMessage()) +// , 0 +// ); +// LoggerUtil.getGlobalLogger().error(e.getMessage(), e); +// } +// +// } } diff --git a/src/main/java/ru/fusionsoft/dbgit/core/DBConnection.java b/src/main/java/ru/fusionsoft/dbgit/core/DBConnection.java index fb714e9..d5d045f 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/DBConnection.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/DBConnection.java @@ -1,145 +1,154 @@ -package ru.fusionsoft.dbgit.core; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.sql.Connection; -import java.sql.DriverManager; -import java.util.Enumeration; -import java.util.Properties; - -import org.slf4j.Logger; - -import ru.fusionsoft.dbgit.utils.ConsoleWriter; -import ru.fusionsoft.dbgit.utils.LoggerUtil; - -/** - * Class for real connection to Database. Load parameters connection from .dblink file - * DBConnection is Singleton - * - * @author mikle - * - */ -public class DBConnection { - private static DBConnection dbGitConnection = null; - private Connection connect = null; - private Logger logger = LoggerUtil.getLogger(this.getClass()); - private DBGitLang lang = DBGitLang.getInstance(); - - private DBConnection(Boolean isConnect) throws ExceptionDBGit { - try { - Properties props = new Properties(); - String url = loadFileDBLink(props); - - if (url != null && isConnect) { - props.put("characterEncoding", "UTF-8"); - connect = DriverManager.getConnection(url, props); - connect.setAutoCommit(false); - } - } catch(Exception e) { - logger.error(lang.getValue("errors", "connectionError").toString(), e); - throw new ExceptionDBGit(e); - } - - } - - public void flushConnection() { - dbGitConnection = null; - } - - public static DBConnection getInstance() throws ExceptionDBGit { - return getInstance(true); - } - - public static DBConnection getInstance(Boolean isConnect) throws ExceptionDBGit { - if (dbGitConnection == null) { - dbGitConnection = new DBConnection(isConnect); - } - return dbGitConnection; - } - - public Connection getConnect() throws ExceptionDBGit { - return connect; - } - - public boolean testingConnection() { - try { - Properties props = new Properties(); - String url = loadFileDBLink(props); - - Connection conTest = DriverManager.getConnection(url, props); - ConsoleWriter.printlnGreen(lang.getValue("general", "link", "connectionEstablished")); - conTest.close(); - conTest = null; - return true; - } catch(Exception e) { - ConsoleWriter.printlnRed(lang.getValue("errors", "link", "cantConnect") + ": " + e.getMessage()); - return false; - } - } - - public boolean testingConnection(String url, Properties props) { - try { - Connection conTest = DriverManager.getConnection(url, props); - ConsoleWriter.printlnGreen(lang.getValue("general", "link", "connectionEstablished")); - conTest.close(); - conTest = null; - return true; - } catch(Exception e) { - ConsoleWriter.printlnRed(lang.getValue("errors", "link", "cantConnect") + ": " + e.getMessage()); - return false; - } - } - - public static void createFileDBLink(String url, Properties props, boolean isDefault) throws ExceptionDBGit { - try{ - File file; - - if (isDefault) - file = new File(DBGitPath.getFullPath(DBGitPath.DB_LINK_DEF_FILE)); - else - file = new File(DBGitPath.getFullPath(DBGitPath.DB_LINK_FILE)); - - DBGitPath.createDir(file.getParent()); - - DBGitPath.createDefaultDbgitConfig(DBGitPath.getFullPath()); - DBGitPath.createLogDir(); - DBGitPath.createScriptsDir(); - - FileWriter writer = new FileWriter(file.getAbsolutePath()); - writer.write("url="+url+"\n"); - Enumeration e = props.propertyNames(); - - while (e.hasMoreElements()) { - String key = (String) e.nextElement(); - writer.write(key+"="+ props.getProperty(key)+"\n"); - } - writer.close(); - ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "link", "dblinkCreated").withParams(DBGitPath.getFullPath(DBGitPath.DB_LINK_FILE))); - } catch(Exception e) { - throw new ExceptionDBGit(e); - } - } - - public static String loadFileDBLink(Properties props) throws ExceptionDBGit { - try{ - File file = new File(DBGitPath.getFullPath(DBGitPath.DB_LINK_FILE)); - File fileDef = new File(DBGitPath.getFullPath(DBGitPath.DB_LINK_DEF_FILE)); - - if (!file.exists() && !fileDef.exists()) { - return null; - } - - FileInputStream fis = new FileInputStream(file.exists() ? file : fileDef); - props.load(fis); - fis.close(); - - String url = props.getProperty("url"); - props.remove("url"); - - return url; - } catch(Exception e) { - throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "fileLoadError").withParams(DBGitPath.DB_LINK_FILE), e); - } - } -} +package ru.fusionsoft.dbgit.core; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.Enumeration; +import java.util.Properties; + +import org.slf4j.Logger; + +import ru.fusionsoft.dbgit.utils.ConsoleWriter; +import ru.fusionsoft.dbgit.utils.LoggerUtil; + +/** + * Class for real connection to Database. Load parameters connection from .dblink file + * DBConnection is Singleton + * + * @author mikle + * + */ +public class DBConnection { + private static DBConnection dbGitConnection = null; + private static int messageLevel = 1; + private Connection connect = null; + private Logger logger = LoggerUtil.getLogger(this.getClass()); + private DBGitLang lang = DBGitLang.getInstance(); + + private DBConnection(Boolean isConnect) throws ExceptionDBGit { + try { + Properties props = new Properties(); + String url = loadFileDBLink(props); + + if (url != null && isConnect) { + props.put("characterEncoding", "UTF-8"); + connect = DriverManager.getConnection(url, props); + connect.setAutoCommit(false); + } + } catch(Exception e) { + logger.error(lang.getValue("errors", "connectionError").toString(), e); + throw new ExceptionDBGit(e); + } + + } + + public void flushConnection() { + dbGitConnection = null; + } + + public static DBConnection getInstance() throws ExceptionDBGit { + return getInstance(true); + } + + public static DBConnection getInstance(Boolean isConnect) throws ExceptionDBGit { + if (dbGitConnection == null) { + dbGitConnection = new DBConnection(isConnect); + } + return dbGitConnection; + } + + public Connection getConnect() throws ExceptionDBGit { + return connect; + } + + public boolean testingConnection() { + try { + Properties props = new Properties(); + String url = loadFileDBLink(props); + + Connection conTest = DriverManager.getConnection(url, props); + ConsoleWriter.printlnGreen(lang.getValue("general", "link", "connectionEstablished"), messageLevel); + conTest.close(); + conTest = null; + return true; + } catch(Exception e) { + ConsoleWriter.printlnRed(lang.getValue("errors", "link", "cantConnect").withParams(e.getMessage()), messageLevel); + return false; + } + } + + public boolean testingConnection(String url, Properties props) { + try { + Connection conTest = DriverManager.getConnection(url, props); + ConsoleWriter.printlnGreen(lang.getValue("general", "link", "connectionEstablished"), messageLevel); + conTest.close(); + conTest = null; + return true; + } catch(Exception e) { + ConsoleWriter.printlnRed(lang.getValue("errors", "link", "cantConnect").withParams(e.getMessage()), messageLevel); + return false; + } + } + + public static void createFileDBLink(String url, Properties props, boolean isDefault) throws ExceptionDBGit { + try{ + File file; + + if (isDefault) + file = new File(DBGitPath.getFullPath(DBGitPath.DB_LINK_DEF_FILE)); + else + file = new File(DBGitPath.getFullPath(DBGitPath.DB_LINK_FILE)); + + DBGitPath.createDir(file.getParent()); + + DBGitPath.createDefaultDbgitConfig(DBGitPath.getFullPath()); + DBGitPath.createLogDir(); + DBGitPath.createScriptsDir(); + + FileWriter writer = new FileWriter(file.getAbsolutePath()); + writer.write("url="+url+"\n"); + Enumeration e = props.propertyNames(); + + while (e.hasMoreElements()) { + String key = (String) e.nextElement(); + writer.write(key+"="+ props.getProperty(key)+"\n"); + } + writer.close(); + ConsoleWriter.detailsPrintln( + DBGitLang.getInstance().getValue("general", "link", "dblinkCreated") + .withParams(DBGitPath.getFullPath(DBGitPath.DB_LINK_FILE)) + , messageLevel + ); + } catch(Exception e) { + throw new ExceptionDBGit(e); + } + } + + public static String loadFileDBLink(Properties props) throws ExceptionDBGit { + try{ + File file = new File(DBGitPath.getFullPath(DBGitPath.DB_LINK_FILE)); + File fileDef = new File(DBGitPath.getFullPath(DBGitPath.DB_LINK_DEF_FILE)); + + if (!file.exists() && !fileDef.exists()) { + return null; + } + + FileInputStream fis = new FileInputStream(file.exists() ? file : fileDef); + props.load(fis); + fis.close(); + + String url = props.getProperty("url"); + props.remove("url"); + + return url; + } catch(Exception e) { + throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "fileLoadError").withParams(DBGitPath.DB_LINK_FILE), e); + } + } + + public static boolean hasInstance(){ + return dbGitConnection != null; + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/core/DBGit.java b/src/main/java/ru/fusionsoft/dbgit/core/DBGit.java index 26979fc..16076de 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/DBGit.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/DBGit.java @@ -1,27 +1,23 @@ package ru.fusionsoft.dbgit.core; import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Set; -import org.eclipse.jgit.api.CheckoutCommand; -import org.eclipse.jgit.api.FetchCommand; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.InitCommand; +import org.eclipse.jgit.api.*; import org.eclipse.jgit.api.ListBranchCommand.ListMode; -import org.eclipse.jgit.api.MergeCommand; -import org.eclipse.jgit.api.MergeResult; -import org.eclipse.jgit.api.PullCommand; -import org.eclipse.jgit.api.RemoteAddCommand; -import org.eclipse.jgit.api.RemoteRemoveCommand; import org.eclipse.jgit.api.ResetCommand.ResetType; -import org.eclipse.jgit.api.Status; +import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.PushResult; @@ -35,58 +31,84 @@ import ru.fusionsoft.dbgit.utils.MaskFilter; public class DBGit { - private static DBGit dbGit = null; - private Repository repository; - private Git git; + private static DBGit instance; + final private Repository repository; + final private Git git; + final private static int messageLevel = 0; - private DBGit() throws ExceptionDBGit { + + private DBGit() { try { FileRepositoryBuilder builder = new FileRepositoryBuilder(); repository = builder - .readEnvironment() // scan environment GIT_* variables - .findGitDir() // scan up the file system tree - .build(); + .setGitDir( + Paths.get("") + .resolve(".git") + .toAbsolutePath() + .toFile() + ) + .build(); git = new Git(repository); - } catch (Exception e) { - throw new ExceptionDBGit(e); + instance = this; + } catch (IOException e) { + final String msg = "Could not build file repository, never intended to do anything after that..."; + throw new ExceptionDBGitRunTime(msg, e); } + } - public static DBGit getInstance() throws ExceptionDBGit { - if (dbGit == null) { + private DBGit(String url) { + try { + //TODO find out where this 'url' is in 'repository' FileRepositoryBuilder builder = new FileRepositoryBuilder(); + repository = builder + .setGitDir(new File(url)) + .build(); + + git = new Git(repository); + } catch (Exception e) { + throw new ExceptionDBGitRunTime(e); + } + } + + public static DBGit getInstance() { + if (instance == null) { - if (builder.readEnvironment().findGitDir().getGitDir() == null) { - throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "gitRepNotFound")); + if (!repositoryExists()) { + final DBGitLang msg = DBGitLang.getInstance().getValue("errors", "gitRepNotFound"); + throw new ExceptionDBGitRunTime(msg); } - dbGit = new DBGit(); + instance = new DBGit(); } - return dbGit; + return instance; } - public static boolean checkIfRepositoryExists() throws ExceptionDBGit { - if (dbGit == null) { - FileRepositoryBuilder builder = new FileRepositoryBuilder(); - - if (builder.readEnvironment().findGitDir().getGitDir() == null) { - return false; - } else { - return true; + public static void initUrlInstance(String gitDirUrl, boolean force) { + if (instance != null) { + if(!force) { + final String msg = "DBGit is already initialized, btw u can set 'force' to 'true' or never make singletons..."; + throw new ExceptionDBGitRunTime(msg); } + instance.repository.close(); + instance.git.close(); + } + instance = new DBGit(gitDirUrl); + } - } else - return true; + public static boolean repositoryExists() { + if (instance == null) { + FileRepositoryBuilder builder = new FileRepositoryBuilder(); + return builder.readEnvironment().findGitDir().getGitDir() != null; + } + else return true; } public Repository getRepository() { return repository; } - public void setRepository(Repository repository) { - this.repository = repository; - } public String getRootDirectory() { return repository.getDirectory().getParent(); @@ -192,7 +214,7 @@ public void gitCommit(boolean existsSwitchA, String msg, String path) throws Exc for (IMetaObject obj : fileObjs.values()) { String hash = obj.getHash(); if (!gmdm.loadFromDB(obj)) { - ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "commit", "cantFindObject")); + ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "commit", "cantFindObject"), messageLevel); obj.removeFromGit(); index.markItemToDelete(obj); index.saveDBIndex(); @@ -226,56 +248,121 @@ public void gitCommit(boolean existsSwitchA, String msg, String path) throws Exc res = git.commit().setAll(existsSwitchA).setOnly(DBGitPath.DB_GIT_PATH + "/" + path).call(); } } - ConsoleWriter.printlnGreen(DBGitLang.getInstance().getValue("general", "commit", "commit") + ": " + res.getName()); - ConsoleWriter.printlnGreen(res.getAuthorIdent().getName() + "<" + res.getAuthorIdent().getEmailAddress() + ">, " + res.getAuthorIdent().getWhen()); + ConsoleWriter.printlnGreen(DBGitLang.getInstance().getValue("general", "commit", "commit") + ": " + res.getName() + , messageLevel + ); + ConsoleWriter.printlnGreen(res.getAuthorIdent().getName() + "<" + res.getAuthorIdent().getEmailAddress() + ">, " + res.getAuthorIdent().getWhen() + , messageLevel + ); } catch (Exception e) { throw new ExceptionDBGit(e); } } - public void gitCheckout(String branch, String commit, boolean isNewBranch) throws ExceptionDBGit { - try { - ConsoleWriter.detailsPrintLn(DBGitLang.getInstance().getValue("general", "checkout", "toCreateBranch") + ": " + isNewBranch); - ConsoleWriter.detailsPrintLn(DBGitLang.getInstance().getValue("general", "checkout", "branchName") + ": " + branch); - if (commit != null) - ConsoleWriter.detailsPrintLn(DBGitLang.getInstance().getValue("general", "checkout", "commitName") + ": " + commit); - - Ref result; - if (git.getRepository().findRef(branch) != null || isNewBranch) { - - CheckoutCommand checkout = git.checkout().setCreateBranch(isNewBranch).setName(branch); - - if (commit != null) - checkout = checkout.setStartPoint(commit); - else { - if (git.branchList().setListMode(ListMode.REMOTE).call().stream() - .filter(ref -> ref.getName().equals("refs/remotes/origin/" + branch)) - .count() > 0) - checkout = checkout.setStartPoint("remotes/origin/" + branch); - } - - result = checkout.call(); + public void printCurrentCommit() throws IOException { + try (RevWalk walk = new RevWalk(repository)) { + ConsoleWriter.detailsPrintlnGreen( + DBGitLang.getInstance().getValue("general", "checkout", "commitMessage") + .withParams(walk.parseCommit(repository.getAllRefs().get("HEAD").getObjectId()).getShortMessage()) + , messageLevel + 1 + ); + } + } + + public boolean nameInLocalRepoExistence(String name) throws IOException { + return git.getRepository().findRef(name) != null; + } + + public boolean nameInRemoteRepoExistence(String name) throws GitAPIException { + return git.branchList().setListMode(ListMode.REMOTE).call().stream() + .anyMatch(ref -> ref.getName().equals("refs/remotes/origin/" + name)); + } + + public void gitCheckoutName(String name) throws Exception { + final CheckoutCommand checkoutCommand = git.checkout().setName(name); + + if (nameInLocalRepoExistence(name)) { + ConsoleWriter.detailsPrintlnGreen( + DBGitLang.getInstance().getValue("general", "checkout", "branchName").withParams(name), messageLevel + 1 + ); + if(nameInRemoteRepoExistence(name)) { + checkoutCommand.setStartPoint("origin/" + name); + } + } else { + ConsoleWriter.detailsPrintlnGreen( + DBGitLang.getInstance().getValue("general", "checkout", "commitName").withParams(name), messageLevel + 1 + ); + } - ConsoleWriter.printlnGreen(result.getName()); + checkoutCommand.call(); + printCurrentCommit(); + } + + public void gitCheckoutNewBranch(String branchName, String commitHash) throws Exception { + final CheckoutCommand checkoutCommand = git.checkout(); + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "checkout", "branchName").withParams(branchName), messageLevel + 1); + if(commitHash != null) { + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "checkout", "commitName").withParams(commitHash), messageLevel + 1); + } + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "checkout", "toCreateBranch").withParams(String.valueOf(true)), messageLevel + 1); + + checkoutCommand.setCreateBranch(true); + checkoutCommand.setName(branchName); + if(commitHash != null) { + if(nameInLocalRepoExistence(commitHash)) { + checkoutCommand.setStartPoint(commitHash); } else { - MaskFilter maskAdd = new MaskFilter(branch); - - int counter = 0; - for (String path: getGitIndexFiles(DBGitPath.DB_GIT_PATH)) { - if (maskAdd.match(path)) { - result = git.checkout().setName(git.getRepository().getBranch()).addPath(DBGitPath.DB_GIT_PATH + "/" + path).call(); - counter++; - } - } - String s = ""; - if (counter != 1) s = "s"; - ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "checkout", "updatedFromIndex").withParams(String.valueOf(counter), s)); + throw new ExceptionDBGit("Can not find the local commit specified: " + commitHash); + } + } else if (nameInRemoteRepoExistence(branchName)){ + checkoutCommand.setStartPoint("origin/" + branchName); + } + //else { + // you would checkout HEAD - create new branch from current one's HEAD + // https://stackoverflow.com/a/37131407 + //} + checkoutCommand.call(); + } + + public void gitCheckoutFileName(String fileName) throws Exception{ + MaskFilter maskAdd = new MaskFilter(fileName); + ConsoleWriter.println("Checking out files...", messageLevel+1); + + int counter = 0; + for (String path : getGitIndexFiles(DBGitPath.DB_GIT_PATH)) { + if (maskAdd.match(path)) { + git.checkout() + .setName(git.getRepository() + .getBranch()) + .addPath(DBGitPath.DB_GIT_PATH + "/"+ path) + .call(); + counter++; + } + } + String messageTailChars = counter != 1 ? "s" : ""; + ConsoleWriter.println( + DBGitLang.getInstance().getValue("general", "checkout", "updatedFromIndex") + .withParams(String.valueOf(counter), messageTailChars) + , messageLevel+1 + ); + } + + public void gitCheckout(String arg1, String arg2, boolean isNewBranch) throws ExceptionDBGit { + try { + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "checkout", "do"), messageLevel); + if(isNewBranch) { + gitCheckoutNewBranch(arg1, arg2); + } else { +// if(nameInRemoteRepoExistence(arg1) || nameInLocalRepoExistence(arg1)) { + gitCheckoutName(arg1); +// } else { +// gitCheckoutFileName(arg1); +// } } - } catch (Exception e) { - throw new ExceptionDBGit(e.getLocalizedMessage()); + throw new ExceptionDBGit("Failed to do checkout", e); } } @@ -289,7 +376,7 @@ public void gitMerge(Set branches) throws ExceptionDBGit { MergeResult result = merge.call(); - ConsoleWriter.println(result.getMergeStatus().toString()); + ConsoleWriter.println(result.getMergeStatus().toString(), 1); } catch (Exception e) { throw new ExceptionDBGit(e); @@ -306,9 +393,16 @@ public void gitPull(String remote, String remoteBranch) throws ExceptionDBGit { if (remoteBranch.length() > 0) pull = pull.setRemoteBranchName(remoteBranch); - ConsoleWriter.printlnGreen(pull.setCredentialsProvider(getCredentialsProviderByName(pull.getRemote())).call().toString()); + ConsoleWriter.printlnGreen( + pull.setCredentialsProvider(getCredentialsProviderByName(pull.getRemote())).call() + .toString() + , 1 + ); } catch (Exception e) { - ConsoleWriter.println("Repo is empty!"); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("errors", "pull", "emptyGitRepository") + , 0 + ); //throw new ExceptionDBGit(e); } } @@ -317,32 +411,81 @@ public void gitPush(String remoteName) throws ExceptionDBGit { try { git.log().call(); } catch (Exception e) { - ConsoleWriter.println("No commits found!"); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "push", "noCommitsFound") + , messageLevel + ); return; } try { - ConsoleWriter.detailsPrintLn("Entered to gitPush"); - ConsoleWriter.detailsPrintLn("remoteName: " + (remoteName.equals("") ? Constants.DEFAULT_REMOTE_NAME : remoteName)); - - Iterable result = git.push() - .setCredentialsProvider(getCredentialsProviderByName(remoteName.equals("") ? Constants.DEFAULT_REMOTE_NAME : remoteName)) - .setRemote(remoteName.equals("") ? Constants.DEFAULT_REMOTE_NAME : remoteName).call(); - - ConsoleWriter.detailsPrintLn("Push called "); - - result.forEach(pushResult -> { - if (pushResult == null) - ConsoleWriter.detailsPrintLn("Push result is null!!! "); - pushResult.toString(); - for (RemoteRefUpdate res : pushResult.getRemoteUpdates()) { - if (res.getStatus() == RemoteRefUpdate.Status.UP_TO_DATE) - ConsoleWriter.println("Everything up-to-date"); - else { - ConsoleWriter.println(res.toString()); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "push", "remoteName") + .withParams((remoteName.equals("") ? Constants.DEFAULT_REMOTE_NAME : remoteName)) + , messageLevel+1 + ); + + try { + + Iterable result = git + .push() + .setCredentialsProvider( + getCredentialsProviderByName( + remoteName.equals("") + ? Constants.DEFAULT_REMOTE_NAME + : remoteName + ) + ) + .setRemote( + remoteName.equals("") + ? Constants.DEFAULT_REMOTE_NAME + : remoteName + ) + .call(); + + + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "push", "called") + , messageLevel+1 + ); + + result.forEach(pushResult -> { + if (pushResult == null){ + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "push", "nullResult") + , 1 + ); + } else { + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "push", "callResult") + .withParams(pushResult.toString()) + , messageLevel+1 + ); } - } - }); + for (RemoteRefUpdate res : pushResult.getRemoteUpdates()) { + if (res.getStatus() == RemoteRefUpdate.Status.UP_TO_DATE){ + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "push", "upToDate") + , 1 + ); + } + else { + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "push", "result") + .withParams(res.toString()) + , 1 + ); + } + } + }); + + } catch (Exception ex) { + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "push", "callResult") + .withParams(ex.getLocalizedMessage()) + , messageLevel + 1 + ); + } } catch (Exception e) { throw new ExceptionDBGit(e); @@ -363,19 +506,28 @@ public static void gitInit(String dirPath) throws ExceptionDBGit { init.call(); - ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "init", "created")); + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "init", "created"), messageLevel); } catch (Exception e) { throw new ExceptionDBGit(e); } } - public static void gitClone(String link, String remoteName) throws ExceptionDBGit { + public static void gitClone(String link, String remoteName, File directory) throws ExceptionDBGit { try { - Git.cloneRepository().setURI(link).setCredentialsProvider(getCredentialsProvider(link)) - .setRemote(remoteName.equals("") ? Constants.DEFAULT_REMOTE_NAME : remoteName).call(); + String actualRemoteName = remoteName.equals("") ? Constants.DEFAULT_REMOTE_NAME : remoteName; + CredentialsProvider cp = getCredentialsProvider(link); + CloneCommand cc = Git.cloneRepository() + .setURI(link) + .setRemote(actualRemoteName) + .setCredentialsProvider(cp) + .setDirectory(directory); - ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "clone", "cloned")); + final Git call = cc.call(); + call.getRepository().close(); + call.close(); + + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "clone", "cloned"), messageLevel); } catch (Exception e) { throw new ExceptionDBGit(e); @@ -387,7 +539,7 @@ public void gitRemote(String command, String name, String uri) throws ExceptionD try { switch (command) { case "" : { - git.remoteList().call().forEach(remote -> ConsoleWriter.println(remote.getName())); + git.remoteList().call().forEach(remote -> ConsoleWriter.println(remote.getName(), messageLevel+1)); break; } @@ -396,8 +548,9 @@ public void gitRemote(String command, String name, String uri) throws ExceptionD remote.setName(name); remote.setUri(new URIish(uri)); remote.call(); + remote.getRepository().close(); - ConsoleWriter.printlnGreen(DBGitLang.getInstance().getValue("general", "remote", "added")); + ConsoleWriter.printlnGreen(DBGitLang.getInstance().getValue("general", "remote", "added"), messageLevel); break; } @@ -406,13 +559,14 @@ public void gitRemote(String command, String name, String uri) throws ExceptionD RemoteRemoveCommand remote = git.remoteRemove(); remote.setName(name); remote.call(); + remote.getRepository().close(); - ConsoleWriter.printlnGreen(DBGitLang.getInstance().getValue("general", "remote", "removed")); + ConsoleWriter.printlnGreen(DBGitLang.getInstance().getValue("general", "remote", "removed"), messageLevel); break; } - default : ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "remote", "unknown")); + default : ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "remote", "unknown"), messageLevel); } } catch (Exception e) { @@ -426,7 +580,7 @@ public void gitReset(String mode) throws ExceptionDBGit { git.reset().call(); else git.reset().setMode(ResetType.valueOf(mode)).call(); - ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "done")); + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "done"), messageLevel); } catch (Exception e) { throw new ExceptionDBGit(e); } @@ -434,8 +588,14 @@ public void gitReset(String mode) throws ExceptionDBGit { public void gitFetch(String remote) throws ExceptionDBGit { try { - FetchCommand fetch = git.fetch() - .setCredentialsProvider(getCredentialsProviderByName(remote.equals("") ? Constants.DEFAULT_REMOTE_NAME : remote)); + FetchCommand fetch = git + .fetch() + .setCredentialsProvider(getCredentialsProviderByName( + remote.equals("") + ? Constants.DEFAULT_REMOTE_NAME + : remote + ) + ); if (remote.length() > 0) fetch = fetch.setRemote(remote); @@ -443,17 +603,25 @@ public void gitFetch(String remote) throws ExceptionDBGit { fetch = fetch.setRemote(Constants.DEFAULT_REMOTE_NAME); fetch.call(); + fetch.getRepository().close(); - ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "done")); + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "done"), messageLevel); } catch (Exception e) { throw new ExceptionDBGit(e); } } private CredentialsProvider getCredentialsProviderByName(String remoteName) throws ExceptionDBGit { - ConsoleWriter.detailsPrintLn("Getting link to repo... "); + ConsoleWriter.detailsPrintln(DBGitLang.getInstance() + .getValue("general", "gettingRepoLink") + , messageLevel + ); String link = git.getRepository().getConfig().getString("remote", remoteName, "url"); - ConsoleWriter.detailsPrintLn("link:" + link); + ConsoleWriter.detailsPrintln(DBGitLang.getInstance() + .getValue("general", "repoLink") + .withParams(link) + , messageLevel + ); if (link != null) return getCredentialsProvider(link); @@ -468,12 +636,15 @@ private CredentialsProvider getCredentialsProvider() throws ExceptionDBGit { private static CredentialsProvider getCredentialsProvider(String link) throws ExceptionDBGit { try { - ConsoleWriter.detailsPrintLn("Getting credentials..."); URIish uri = new URIish(link); - ConsoleWriter.detailsPrintLn("uri login = " + uri.getUser()); - ConsoleWriter.detailsPrintLn("uri pass = " + uri.getPass()); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "showDbCredentials") + .withParams( uri.getScheme(), uri.getUser(), uri.getHost(), uri.getRawPath()) + , 0 + ); + /* Pattern patternPass = Pattern.compile("(?<=:(?!\\/))(.*?)(?=@)"); Pattern patternLogin = Pattern.compile("(?<=\\/\\/)(.*?)(?=:(?!\\/))"); @@ -499,6 +670,10 @@ private static CredentialsProvider getCredentialsProvider(String link) throws Ex ConsoleWriter.detailsPrintLn("login: " + login); ConsoleWriter.detailsPrintLn("pass: " + pass);*/ + if(uri.getUser() == null) { + ConsoleWriter.detailsPrintlnRed(DBGitLang.getInstance().getValue("errors", "gitLoginNotFound"), messageLevel); + return null; + } return new UsernamePasswordCredentialsProvider(uri.getUser(), uri.getPass()); } catch (Exception e) { throw new ExceptionDBGit(e); diff --git a/src/main/java/ru/fusionsoft/dbgit/core/DBGitConfig.java b/src/main/java/ru/fusionsoft/dbgit/core/DBGitConfig.java index 3c5c956..d81c84c 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/DBGitConfig.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/DBGitConfig.java @@ -1,155 +1,182 @@ -package ru.fusionsoft.dbgit.core; - -import java.io.File; - -import org.ini4j.Ini; - -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class DBGitConfig { - - private static DBGitConfig config = null; - private Ini ini = null; - private Ini iniGlobal = null; - - private DBGitConfig() throws Exception { - - if (DBGit.checkIfRepositoryExists()) { - File file = new File(DBGitPath.getFullPath() + "/" + DBGitPath.DBGIT_CONFIG); - if (file.exists()) - ini = new Ini(file); - } - - String path = new File(DBGitConfig.class.getProtectionDomain().getCodeSource().getLocation() - .toURI()).getAbsolutePath(); - - //for debug: - if (path.contains("classes")) path = path + "/../dbgit"; - - while (!new File(path + "/dbgitconfig").exists()) { - int i = path.lastIndexOf("/"); - if (i == -1) i = path.lastIndexOf("\\"); - - path = path.substring(0, i); - } - - if (new File(path + "/bin/dbgitconfig").exists()) - path = path + "/bin/dbgitconfig"; - else - path = path + "/dbgitconfig"; - - File fileGlobal = new File(path); - if (fileGlobal.exists()) - iniGlobal = new Ini(fileGlobal); - } - - public static DBGitConfig getInstance() throws Exception { - if (config == null) - config = new DBGitConfig(); - - return config; - } - - public String getString(String section, String option, String defaultValue) { - return getString(section, option, defaultValue, false); - } - - public Boolean getBoolean(String section, String option, Boolean defaultValue) { - return getBoolean(section, option, defaultValue, false); - } - - public Integer getInteger(String section, String option, Integer defaultValue) { - return getInteger(section, option, defaultValue, false); - } - - public Double getDouble(String section, String option, Double defaultValue) { - return getDouble(section, option, defaultValue, false); - } - - public String getStringGlobal(String section, String option, String defaultValue) { - return getString(section, option, defaultValue, true); - } - - public Boolean getBooleanGlobal(String section, String option, Boolean defaultValue) { - return getBoolean(section, option, defaultValue, true); - } - - public Integer getIntegerGlobal(String section, String option, Integer defaultValue) { - return getInteger(section, option, defaultValue, true); - } - - public Double getDoubleGlobal(String section, String option, Double defaultValue) { - return getDouble(section, option, defaultValue, true); - } - - private String getString(String section, String option, String defaultValue, boolean global) { - try { - String result = global ? iniGlobal.get(section, option) : ini.get(section, option); - return result == null ? defaultValue : result; - } catch (Exception e) { - return defaultValue; - } - } - - private Boolean getBoolean(String section, String option, Boolean defaultValue, boolean global) { - try { - String result = global ? iniGlobal.get(section, option) : ini.get(section, option); - - return result == null ? defaultValue : Boolean.valueOf(result); - } catch (Exception e) { - return defaultValue; - } - } - - private Integer getInteger(String section, String option, Integer defaultValue, boolean global) { - try { - String result = global ? iniGlobal.get(section, option) : ini.get(section, option); - return result == null ? defaultValue : Integer.valueOf(result); - } catch (Exception e) { - return defaultValue; - } - } - - private Double getDouble(String section, String option, Double defaultValue, boolean global) { - try { - String result = global ? iniGlobal.get(section, option) : ini.get(section, option); - return result == null ? defaultValue : Double.valueOf(result); - } catch (Exception e) { - return defaultValue; - } - } - - public void setValue(String parameter, String value) throws ExceptionDBGit { - setValue(parameter, value, false); - } - - public void setValueGlobal(String parameter, String value) throws ExceptionDBGit { - setValue(parameter, value, true); - } - - public void setValue(String parameter, String value, boolean global) throws ExceptionDBGit { - try { - if (global) { - if (!iniGlobal.get("core").containsKey(parameter)) - ConsoleWriter.detailsPrintLn(DBGitLang.getInstance().getValue("errors", "config", "noParameter").withParams(parameter)); - else { - iniGlobal.get("core").put(parameter, value); - iniGlobal.store(iniGlobal.getFile()); - } - } else { - if (ini == null) - throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "gitRepNotFound")); - - if (!ini.get("core").containsKey(parameter)) - ConsoleWriter.detailsPrintLn(DBGitLang.getInstance().getValue("errors", "config", "noParameter").withParams(parameter)); - else { - ini.get("core").put(parameter, value); - ini.store(new File(DBGitPath.getFullPath() + "/" + DBGitPath.DBGIT_CONFIG)); - } - } - } catch (Exception e) { - throw new ExceptionDBGit(e); - } - } - -} +package ru.fusionsoft.dbgit.core; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; + +import org.ini4j.Ini; + +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class DBGitConfig { + private static int messageLevel = 1; + private static DBGitConfig config = null; + private Ini ini = null; + private Ini iniGlobal = null; + private Map transientConfig = new HashMap<>(); + + private DBGitConfig() { + try{ + findAndSetIni(); + findAndSetIniGlobal(); + } catch (Exception anyKindOfException){ + //no reason to continue anything + throw new ExceptionDBGitRunTime(anyKindOfException); + } + } + + public static DBGitConfig getInstance() { + if (config == null) config = new DBGitConfig(); + return config; + } + + private void findAndSetIniGlobal() throws URISyntaxException, IOException { + String path = new File(DBGitConfig.class.getProtectionDomain() + .getCodeSource().getLocation().toURI() + ).getAbsolutePath(); + + //for debug: + if (path.contains("classes")) path = path + "/../dbgit"; + + while (!new File(path + "/dbgitconfig").exists()) { + int i = path.lastIndexOf("/"); + if (i == -1) i = path.lastIndexOf("\\"); + + path = path.substring(0, i); + } + + if (new File(path + "/bin/dbgitconfig").exists()) + path = path + "/bin/dbgitconfig"; + else + path = path + "/dbgitconfig"; + + File fileGlobal = new File(path); + if (fileGlobal.exists()) iniGlobal = new Ini(fileGlobal); + } + + private void findAndSetIni() throws IOException { + if (DBGit.repositoryExists()) { + File file = new File(DBGitPath.getFullPath() + "/" + DBGitPath.DBGIT_CONFIG); + if (file.exists()) ini = new Ini(file); + } + } + + private Ini getIni() throws IOException { + if(ini == null){ + findAndSetIni(); + } + return ini; + } + + public String getString(String section, String option, String defaultValue) { + return getString(section, option, defaultValue, false); + } + public Boolean getBoolean(String section, String option, Boolean defaultValue) { + return getBoolean(section, option, defaultValue, false); + } + public Integer getInteger(String section, String option, Integer defaultValue) { + return getInteger(section, option, defaultValue, false); + } + public Double getDouble(String section, String option, Double defaultValue) { + return getDouble(section, option, defaultValue, false); + } + public String getStringGlobal(String section, String option, String defaultValue) { + return getString(section, option, defaultValue, true); + } + public Boolean getBooleanGlobal(String section, String option, Boolean defaultValue) { + return getBoolean(section, option, defaultValue, true); + } + public Integer getIntegerGlobal(String section, String option, Integer defaultValue) { + return getInteger(section, option, defaultValue, true); + } + public Double getDoubleGlobal(String section, String option, Double defaultValue) { + return getDouble(section, option, defaultValue, true); + } + private String getString(String section, String option, String defaultValue, boolean global) { + try { + String result = global ? iniGlobal.get(section, option) : getIni().get(section, option); + return result == null ? defaultValue : result; + } catch (Exception e) { + return defaultValue; + } + } + private Boolean getBoolean(String section, String option, Boolean defaultValue, boolean global) { + try { + String result = global ? iniGlobal.get(section, option) : getIni().get(section, option); + + return result == null ? defaultValue : Boolean.valueOf(result); + } catch (Exception e) { + return defaultValue; + } + } + private Integer getInteger(String section, String option, Integer defaultValue, boolean global) { + try { + String result = global ? iniGlobal.get(section, option) : getIni().get(section, option); + return result == null ? defaultValue : Integer.valueOf(result); + } catch (Exception e) { + return defaultValue; + } + } + private Double getDouble(String section, String option, Double defaultValue, boolean global) { + try { + String result = global ? iniGlobal.get(section, option) : getIni().get(section, option); + return result == null ? defaultValue : Double.valueOf(result); + } catch (Exception e) { + return defaultValue; + } + } + public void setValue(String parameter, String value) throws ExceptionDBGit { + setValue(parameter, value, false); + } + public void setValueGlobal(String parameter, String value) throws ExceptionDBGit { + setValue(parameter, value, true); + } + public void setValue(String parameter, String value, boolean global) throws ExceptionDBGit { + try { + if (global) { + if (!iniGlobal.get("core").containsKey(parameter) /*&& !parameter.equals("CURRENT_OBJECT")*/) + ConsoleWriter.detailsPrintln( + DBGitLang.getInstance().getValue("errors", "config", "noParameter").withParams(parameter) + , messageLevel + ); + else { + iniGlobal.get("core").put(parameter, value); + iniGlobal.store(iniGlobal.getFile()); + } + } else { + if (getIni() == null) + throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "gitRepNotFound")); + + if (!ini.get("core").containsKey(parameter) && ! parameter.equals("CURRENT_OBJECT")) + ConsoleWriter.detailsPrintln(DBGitLang.getInstance().getValue("errors", "config", "noParameter").withParams(parameter), messageLevel); + else { + getIni().get("core").put(parameter, value); + getIni().store(new File(DBGitPath.getFullPath() + "/" + DBGitPath.DBGIT_CONFIG)); + } + } + } catch (Exception e) { + throw new ExceptionDBGit(e); + } + } + + + public static String TO_IGNORE_OWNER = "noowner"; + + public void setValueTransient(String parameter, String value) throws ExceptionDBGit{ + transientConfig.put(parameter, value); + } + + public String getValueTransient(String parameter, String defaultValue){ + return transientConfig.getOrDefault(parameter, defaultValue); + } + + public void setToIgnoreOnwer(boolean value) throws ExceptionDBGit{ + transientConfig.put(TO_IGNORE_OWNER, value ? "true" : "false"); + } + + public boolean getToIgnoreOnwer(boolean defaultValue){ + return Boolean.valueOf(getValueTransient(TO_IGNORE_OWNER, defaultValue ? "true" : "false")); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/core/DBGitIgnore.java b/src/main/java/ru/fusionsoft/dbgit/core/DBGitIgnore.java index ae735ed..e5c4330 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/DBGitIgnore.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/DBGitIgnore.java @@ -6,7 +6,7 @@ import java.util.HashMap; import java.util.Map; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; +import ru.fusionsoft.dbgit.adapters.DBBackupAdapter; import ru.fusionsoft.dbgit.utils.MaskFilter; /** @@ -27,19 +27,35 @@ public class DBGitIgnore { // load file DBIgnore loadFileDBIgnore(); } - + + public DBGitIgnore(Map filters, Map exclusions) { + this.filters = filters; + this.exclusions = exclusions; + } + protected void loadFileDBIgnore() throws ExceptionDBGit { + loadFileDBIgnore(false); + } + protected void loadFileDBIgnore(boolean withBackupSchemas) throws ExceptionDBGit { try{ File file = new File(DBGitPath.getRootPath(DBGitPath.DB_GIT_PATH+"/"+DBGitPath.DB_IGNORE_FILE)); if (!file.exists()) return ; + //boolean isBackupToScheme = DBGitConfig.getInstance().getBoolean("core", "BACKUP_TO_SCHEME", false); BufferedReader br = new BufferedReader(new FileReader(file)); - for(String line; (line = br.readLine()) != null; ) { + for(String line; (line = br.readLine()) != null; ) { + if (line.startsWith("!")) { MaskFilter mask = new MaskFilter(line.substring(1)); exclusions.put(line.substring(1), mask); + if(withBackupSchemas /*&&isBackupToScheme*/){ + String schemaPart = line.substring(1,line.indexOf("/")+1); + String backupSchemeObjExclusion = line.replace(schemaPart, DBBackupAdapter.PREFIX + schemaPart).substring(1); + MaskFilter backupSchemeObjMask = new MaskFilter(backupSchemeObjExclusion); + exclusions.put(backupSchemeObjExclusion, backupSchemeObjMask); + } } else { MaskFilter mask = new MaskFilter(line); 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/DBGitLang.java b/src/main/java/ru/fusionsoft/dbgit/core/DBGitLang.java index a899a65..b4c0698 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/DBGitLang.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/DBGitLang.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.FileInputStream; +import java.util.Arrays; import java.util.Map; import org.yaml.snakeyaml.Yaml; @@ -29,11 +30,16 @@ private DBGitLang() { path = path.substring(0, i); } - mapValue = (Map) - new Yaml().load(new FileInputStream(new File(path + "/lang/" + - DBGitConfig.getInstance().getString("core", "LANG", DBGitConfig.getInstance().getStringGlobal("core", "LANG", "no")).toLowerCase() + ".yaml"))); + mapValue = new Yaml().load( + new FileInputStream( + new File( + path + + "/lang/" + + DBGitConfig.getInstance().getString("core", "LANG", DBGitConfig.getInstance().getStringGlobal("core", "LANG", "no")).toLowerCase() + + ".yaml") + ) + ); } catch (Exception e) { - ConsoleWriter.println(e.getLocalizedMessage()); throw new ExceptionDBGitRunTime(e); } } @@ -43,7 +49,7 @@ public static DBGitLang getInstance() { return lang; } - public DBGitLang getValue(String... args) { + public DBGitLang getValue(String... args) throws ExceptionDBGitRunTime { Object val = mapValue; value = ""; for (String arg : args) { @@ -52,8 +58,13 @@ public DBGitLang getValue(String... args) { val = newVal.get(arg); } - if (val != null) + if (val != null){ value = val.toString(); + if(value.equals("")) throw new ExceptionDBGitRunTime("Empty `lang` value for " + Arrays.toString(args)); + } + else { + throw new ExceptionDBGitRunTime("Cannot find `lang` value for " + Arrays.toString(args)); + } return this; } diff --git a/src/main/java/ru/fusionsoft/dbgit/core/DBGitPath.java b/src/main/java/ru/fusionsoft/dbgit/core/DBGitPath.java index 435cd21..437f33b 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/DBGitPath.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/DBGitPath.java @@ -5,16 +5,11 @@ import java.sql.DriverManager; import java.text.SimpleDateFormat; import java.util.Calendar; -import java.util.Date; import java.util.GregorianCalendar; import java.util.Properties; -import java.util.stream.Stream; - -import javax.print.attribute.standard.DateTimeAtCompleted; import ru.fusionsoft.dbgit.adapters.AdapterFactory; import ru.fusionsoft.dbgit.meta.DBGitMetaType; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.Convertor; /** @@ -89,7 +84,7 @@ public static String getScriptsPath() throws ExceptionDBGit { return dbGit.getRootDirectory()+"/" + DB_GIT_PATH + "/" + SCRIPT_PATH + "/"; } - public static String getFullPath() throws ExceptionDBGit { + public static String getFullPath() { DBGit dbGit = DBGit.getInstance(); return dbGit.getRootDirectory()+"/"+DB_GIT_PATH + "/"; } @@ -100,7 +95,7 @@ public static String getRootPath(String path) throws ExceptionDBGit { } public static boolean isRepositoryExists() throws ExceptionDBGit { - return DBGit.checkIfRepositoryExists(); + return DBGit.repositoryExists(); } public static String getRootPath() throws ExceptionDBGit { @@ -166,8 +161,8 @@ public static boolean createDefaultDbgitConfig(String path) throws ExceptionDBGi writer.write("LOG_ROTATE = 31\n"); writer.write("LANG = ENG\n"); writer.write("SCRIPT_ROTATE = 31\n"); - writer.write("TO_MAKE_BACKUP = true\n"); - writer.write("BACKUP_TO_SCHEME = false\n"); + writer.write("TO_MAKE_BACKUP = false\n"); + writer.write("BACKUP_TO_SCHEME = true\n"); writer.write("BACKUP_TABLEDATA = true\n"); writer.write("PORTION_SIZE = 50000\n"); writer.write("TRY_COUNT = 1000\n"); @@ -200,7 +195,6 @@ public static boolean createDefaultDbignore(String path, String url, Properties return false; } catch(Exception e) { - e.printStackTrace(); throw new ExceptionDBGit(e); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGit.java b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGit.java index 58f3804..8cb9527 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGit.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGit.java @@ -1,10 +1,14 @@ package ru.fusionsoft.dbgit.core; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.LoggerUtil; +import java.sql.Connection; +import java.sql.SQLException; + /** * Base class for all Exception in dbgit project * @@ -14,30 +18,17 @@ public class ExceptionDBGit extends Exception { private static final long serialVersionUID = -4613368557825624023L; - private Logger logger = LoggerUtil.getLogger(this.getClass()); public ExceptionDBGit(Object msg) { - ConsoleWriter.printlnRed(msg); - System.exit(1); - //super(msg); - } - - public ExceptionDBGit(String msg) { - ConsoleWriter.printlnRed(msg); - System.exit(1); - //super(msg); + super(String.valueOf(msg)); } - - public ExceptionDBGit(String message, Throwable cause) { - ConsoleWriter.printlnRed(message); - logger.error(message, cause); - System.exit(1); - //super(message, cause); + public ExceptionDBGit(Object message, Throwable cause) { + super(String.valueOf(message), cause); } - public ExceptionDBGit(Throwable cause) { - logger.error(cause.getLocalizedMessage(), cause); - //super(cause); + super(cause); } + + } diff --git a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitObjectNotFound.java b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitObjectNotFound.java index 0d27866..04a5b09 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitObjectNotFound.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitObjectNotFound.java @@ -1,6 +1,6 @@ package ru.fusionsoft.dbgit.core; -public class ExceptionDBGitObjectNotFound extends ExceptionDBGit { +public class ExceptionDBGitObjectNotFound extends Error { private static final long serialVersionUID = 2163408974338332577L; diff --git a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitRestore.java b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitRestore.java index c9527e5..3ade4de 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitRestore.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitRestore.java @@ -1,23 +1,12 @@ package ru.fusionsoft.dbgit.core; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - public class ExceptionDBGitRestore extends ExceptionDBGit { private static final long serialVersionUID = -8714585942496838509L; - public ExceptionDBGitRestore(String msg) { - super(msg); - ConsoleWriter.println("\n" + msg); - } - - public ExceptionDBGitRestore(String message, Throwable cause) { - super(message, cause); - ConsoleWriter.println("\n" + message + "\n" + cause.getLocalizedMessage()); - } - - public ExceptionDBGitRestore(Throwable cause) { - super(cause); - ConsoleWriter.println(cause.getLocalizedMessage()); - } + public ExceptionDBGitRestore(Object msg) { super(msg); } + public ExceptionDBGitRestore(Object message, Throwable cause) { super(message, cause); } + public ExceptionDBGitRestore(Throwable cause) { super(cause); } + + } diff --git a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitRunTime.java b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitRunTime.java index f730db4..10dda5e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitRunTime.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitRunTime.java @@ -1,29 +1,19 @@ package ru.fusionsoft.dbgit.core; -import org.slf4j.Logger; - -import ru.fusionsoft.dbgit.utils.ConsoleWriter; -import ru.fusionsoft.dbgit.utils.LoggerUtil; public class ExceptionDBGitRunTime extends RuntimeException { private static final long serialVersionUID = 958722213419205629L; - private Logger logger = LoggerUtil.getLogger(this.getClass()); - - public ExceptionDBGitRunTime(String msg) { - super(msg); + + public ExceptionDBGitRunTime(Object msg) { + super(msg.toString()); } - - public ExceptionDBGitRunTime(String message, Throwable cause) { - ConsoleWriter.printlnRed(message); - logger.error(message, cause); - System.exit(1); - //super(message, cause); + + public ExceptionDBGitRunTime(Object message, Throwable cause) { + super(message.toString(), cause); } - + public ExceptionDBGitRunTime(Throwable cause) { - //super(cause); - logger.error(cause.getLocalizedMessage(), cause); + super(cause); } - } diff --git a/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitTableData.java b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitTableData.java new file mode 100644 index 0000000..9bd2cc8 --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/core/ExceptionDBGitTableData.java @@ -0,0 +1,29 @@ +package ru.fusionsoft.dbgit.core; + +public class ExceptionDBGitTableData extends Exception{ + private int errorFlag; + + public ExceptionDBGitTableData(int errorFlag) { + this.errorFlag = errorFlag; + } + + public ExceptionDBGitTableData(String message, int errorFlag) { + super(message); + this.errorFlag = errorFlag; + } + + public ExceptionDBGitTableData(String message, Throwable cause, int errorFlag) { + super(message, cause); + this.errorFlag = errorFlag; + } + + public ExceptionDBGitTableData(Throwable cause, int errorFlag) { + super(cause); + this.errorFlag = errorFlag; + } + + public ExceptionDBGitTableData(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, int errorFlag) { + super(message, cause, enableSuppression, writableStackTrace); + this.errorFlag = errorFlag; + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/core/GitMetaDataManager.java b/src/main/java/ru/fusionsoft/dbgit/core/GitMetaDataManager.java index 7d4a2a2..bf50d04 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/GitMetaDataManager.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/GitMetaDataManager.java @@ -38,13 +38,14 @@ */ public class GitMetaDataManager { private static GitMetaDataManager manager = null; - - protected IMapMetaObject dbObjs; - protected IMapMetaObject fileObjs; - + + protected IMapMetaObject dbObjs; + protected IMapMetaObject fileObjs; + private MetaTableData currentPortion = null; private int currentPortionIndex = 0; - + private static int messageLevel = 1; + protected GitMetaDataManager() { dbObjs = new TreeMapMetaObject(); fileObjs = new TreeMapMetaObject(); @@ -93,13 +94,16 @@ private void addToMapSqlObject( objs.put(obj); } - } + } public boolean loadFromDB(IMetaObject obj) throws ExceptionDBGit { - boolean result = obj.loadFromDB(); - if (result) - dbObjs.put(obj); - return result; + try { + boolean result = obj.loadFromDB(); + if (result) dbObjs.put(obj); + return result; + } catch (ExceptionDBGitObjectNotFound ex) { + return false; + } } public IMetaObject getCacheDBMetaObject(String name) { @@ -126,14 +130,14 @@ public boolean loadNextPortion(MetaTable tbl) throws ExceptionDBGit { if (currentPortion == null || !tbl.getName().replace(".tbl", ".csv") .equalsIgnoreCase(currentPortion.getName())) currentPortionIndex = 0; - ConsoleWriter.detailsPrint(DBGitLang.getInstance().getValue("general", "add", "loading") + " " + currentPortionIndex + ", ", 2); + ConsoleWriter.detailsPrintln(DBGitLang.getInstance().getValue("general", "add", "loading") + " " + currentPortionIndex + ", ", messageLevel); currentPortion = new MetaTableData(tbl.getTable()); if (currentPortion.getmapRows() != null) currentPortion.getmapRows().clear(); if (!currentPortion.loadPortionFromDB(currentPortionIndex)) return false; - ConsoleWriter.detailsPrint(DBGitLang.getInstance().getValue("general", "add", "size") + " " + currentPortion.getmapRows().size() + "\n", 2); + ConsoleWriter.detailsPrintln(DBGitLang.getInstance().getValue("general", "add", "size") + " " + currentPortion.getmapRows().size() , messageLevel); currentPortionIndex++; try { @@ -157,12 +161,13 @@ public void setCurrentPortion(int currentPortionIndex) { * Load meta data from DB * @return */ - public IMapMetaObject loadDBMetaData(boolean toIgnore) throws ExceptionDBGit { + public IMapMetaObject loadDBMetaData(boolean includeBackupSchemas) throws ExceptionDBGit { IDBAdapter adapter = AdapterFactory.createAdapter(); - DBGitIgnore ignore = (toIgnore) - ? DBGitIgnore.getInstance() - : new DBGitIgnore() { @Override protected void loadFileDBIgnore() { }}; + DBGitIgnore ignore = (includeBackupSchemas) + ? new DBGitIgnore() { @Override protected void loadFileDBIgnore() throws ExceptionDBGit { loadFileDBIgnore(true); }} + : DBGitIgnore.getInstance(); + dbObjs.clear(); Map tbls = new HashMap(); @@ -179,10 +184,11 @@ public IMapMetaObject loadDBMetaData(boolean toIgnore) throws ExceptionDBGit { } else { schemes = new HashMap(); try { - schemes.put(adapter.getConnection().getSchema(), new DBSchema(adapter.getConnection().getSchema())); - ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "meta", "cantGetOtherUsersObjects")); + final DBSchema dbSchema = new DBSchema(adapter.getConnection().getSchema()); + schemes.put(adapter.getConnection().getSchema(), dbSchema); + ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "meta", "cantGetOtherUsersObjects"), messageLevel); } catch (SQLException e) { - throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "meta", "cantGetCurrentSchema")); + throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "meta", "cantGetCurrentSchema").toString(), e); } } @@ -235,6 +241,12 @@ public IMapMetaObject loadDBMetaData(boolean toIgnore) throws ExceptionDBGit { 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 @@ -262,7 +274,7 @@ public IMapMetaObject loadDBMetaData(boolean toIgnore) throws ExceptionDBGit { } public IMapMetaObject loadDBMetaData() throws ExceptionDBGit { - return loadDBMetaData(true); + return loadDBMetaData(false); } @@ -273,7 +285,7 @@ public IMapMetaObject loadFileMetaData() throws ExceptionDBGit { public IMapMetaObject loadFileMetaDataForce() throws ExceptionDBGit { return loadFileMetaData(true); } - + /** * Load meta data from git files * @return @@ -285,61 +297,70 @@ public IMapMetaObject loadFileMetaData(boolean force) throws ExceptionDBGit { List files = dbGit.getGitIndexFiles(DBGitPath.DB_GIT_PATH); boolean isSuccessful = true; - + + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "meta", "loadFiles") + .withParams("") + , messageLevel + ); + for (int i = 0; i < files.size(); i++) { String filename = files.get(i); if (DBGitPath.isServiceFile(filename)) continue; - ConsoleWriter.detailsPrint("\nLoading file " + filename + "...", 1); - + + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "meta", "loadFile") + .withParams(filename) + , messageLevel+1 + ); + if (force) { IMetaObject obj = loadMetaFile(filename); - if (obj != null) + if (obj != null) { objs.put(obj); + } -// ConsoleWriter.detailsPrintlnGreen(DBGitLang.getInstance().getValue("errors", "meta", "ok")); } else { try { - Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); IMetaObject obj = loadMetaFile(filename); - Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); - Long diff = timestampAfter.getTime() - timestampBefore.getTime(); - -// ConsoleWriter.detailsPrintlnGreen(DBGitLang.getInstance().getValue("errors", "meta", "okTime").withParams(diff.toString())); - if (obj != null) { objs.put(obj); } } catch (Exception e) { - isSuccessful = false; - ConsoleWriter.detailsPrintlnRed(DBGitLang.getInstance().getValue("errors", "meta", "fail")); - e.printStackTrace(); - ConsoleWriter.detailsPrintLn(e.getMessage()); - - IMetaObject obj = MetaObjectFactory.createMetaObject(filename); - - if (obj != null) - objs.put(obj); +// ConsoleWriter.printlnRed(DBGitLang.getInstance().getValue("errors", "meta", "loadMetaFile") + final String msg = DBGitLang.getInstance() + .getValue("errors", "meta", "cantLoadMetaFile") + .withParams(filename); + throw new ExceptionDBGit(msg, e); +// isSuccessful = false; +// ConsoleWriter.detailsPrintln(e.getMessage(), messageLevel); +// IMetaObject obj = MetaObjectFactory.createMetaObject(filename); +// objs.put(obj); } } } - if (!isSuccessful && !force) { - throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "meta", "invalidFiles")); - } +// if (!isSuccessful && !force) { +// throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "meta", "invalidFiles")); +// } return objs; } catch(Exception e) { throw new ExceptionDBGit(e); } } - + public IMetaObject loadMetaFile(String metaName) throws ExceptionDBGit { + return loadMetaFile(metaName, true); + } + + public IMetaObject loadMetaFile(String metaName, boolean forceLoad) throws ExceptionDBGit { AdapterFactory.createAdapter(); - if (fileObjs.containsKey(metaName)) - return fileObjs.get(metaName); - try { + if (!forceLoad && fileObjs.containsKey(metaName)) return fileObjs.get(metaName); + try + { IMetaObject obj = MetaObjectFactory.createMetaObject(metaName); obj = obj.loadFromFile(); if (obj != null) { diff --git a/src/main/java/ru/fusionsoft/dbgit/core/NotImplementedExceptionDBGitRuntime.java b/src/main/java/ru/fusionsoft/dbgit/core/NotImplementedExceptionDBGitRuntime.java new file mode 100644 index 0000000..4356f0a --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/core/NotImplementedExceptionDBGitRuntime.java @@ -0,0 +1,7 @@ +package ru.fusionsoft.dbgit.core; + +public class NotImplementedExceptionDBGitRuntime extends ExceptionDBGitRunTime { + public NotImplementedExceptionDBGitRuntime(){ + super("Stub class can not use this method"); + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/core/db/FieldType.java b/src/main/java/ru/fusionsoft/dbgit/core/db/FieldType.java index 88bebb6..ba8c754 100644 --- a/src/main/java/ru/fusionsoft/dbgit/core/db/FieldType.java +++ b/src/main/java/ru/fusionsoft/dbgit/core/db/FieldType.java @@ -9,7 +9,10 @@ public enum FieldType { NATIVE("native"), NUMBER("number"), STRING("string"), - TEXT("text"); + STRING_NATIVE("string native"), + ENUM("enum"), + TEXT("text"), + UNDEFINED(""); private String typeName; diff --git a/src/main/java/ru/fusionsoft/dbgit/data_table/BooleanData.java b/src/main/java/ru/fusionsoft/dbgit/data_table/BooleanData.java index cc62bb8..f07d46c 100644 --- a/src/main/java/ru/fusionsoft/dbgit/data_table/BooleanData.java +++ b/src/main/java/ru/fusionsoft/dbgit/data_table/BooleanData.java @@ -7,13 +7,14 @@ public class BooleanData implements ICellData { - private Boolean value; + private boolean value; + private boolean isNull = false; @Override - public boolean loadFromDB(ResultSet rs, String fieldname) throws Exception { - value = rs.getBoolean(fieldname); + public boolean loadFromDB(ResultSet rs, String fieldName) throws Exception { + value = rs.getBoolean(fieldName); if (rs.wasNull()) { - value = null; + isNull = true; } return true; } @@ -25,7 +26,14 @@ public String serialize(DBTable tbl) throws Exception { @Override public void deserialize(String data) throws Exception { - this.value = (data == null) ? null : Boolean.valueOf(data); + //this.value = (data == null) ? null : Boolean.valueOf(data); + if (data == null) { + isNull = true; + value = false; + } else { + isNull = false; + value = Boolean.parseBoolean(data); + } } @Override @@ -40,7 +48,7 @@ public int removeFromGit() throws ExceptionDBGit { @Override public String convertToString() throws Exception { - return value != null ? value.toString() : null; + return !isNull ? String.valueOf(value) : null; } @Override @@ -49,12 +57,13 @@ public Object getWriterForRapair() { } public Boolean getValue() { + if (isNull) return null; return value; } @Override public String getSQLData() { - return (value == null) ? "''" : "\'"+value.toString()+"\'"; + return (isNull) ? "''" : "\'"+String.valueOf(value)+"\'"; } } diff --git a/src/main/java/ru/fusionsoft/dbgit/data_table/DateData.java b/src/main/java/ru/fusionsoft/dbgit/data_table/DateData.java index 0aaa665..095d34e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/data_table/DateData.java +++ b/src/main/java/ru/fusionsoft/dbgit/data_table/DateData.java @@ -10,27 +10,41 @@ import ru.fusionsoft.dbgit.utils.Convertor; public class DateData implements ICellData { - Date value; - SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); + //private Date value; + private long value; + private boolean isNull = false; + public static SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); @Override public boolean loadFromDB(ResultSet rs, String fieldname) throws Exception { - value = rs.getDate(fieldname); + if (rs.getDate(fieldname) == null) { + isNull = true; + value = 0; + } else + value = rs.getDate(fieldname).getTime(); + return true; } @Override public String serialize(DBTable tbl) throws Exception { - return value == null ? null : format.format(value); + return isNull ? null : format.format(new Date(value)); } @Override public void deserialize(String data) throws Exception { - value = (data == null) ? null :new Date(format.parse(data).getTime()); + //value = (data == null) ? null :new Date(format.parse(data).getTime()); + if (data == null) { + isNull = true; + value = 0; + } else { + isNull = false; + value = format.parse(data).getTime(); + } } public void setValue(Date value) { - this.value = value; + this.value = value.getTime(); } @Override @@ -45,7 +59,7 @@ public int removeFromGit() throws ExceptionDBGit { @Override public String convertToString() throws Exception { - return (value == null) ? null : format.format(value); + return isNull ? null : format.format(new Date(value)); } @Override @@ -55,11 +69,11 @@ public Object getWriterForRapair() { @Override public String getSQLData() { - return (value == null) ? "''" : "\'"+format.format(value)+"\'"; + return isNull ? "''" : "\'"+format.format(new Date(value))+"\'"; } public Date getDate() { - return value; + return new Date(value); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/data_table/LongData.java b/src/main/java/ru/fusionsoft/dbgit/data_table/LongData.java index 2bab5bf..0e04dd0 100644 --- a/src/main/java/ru/fusionsoft/dbgit/data_table/LongData.java +++ b/src/main/java/ru/fusionsoft/dbgit/data_table/LongData.java @@ -6,13 +6,14 @@ public class LongData implements ICellData { - private Long value; + private double value; + private boolean isNull = false; @Override public boolean loadFromDB(ResultSet rs, String fieldname) throws Exception { - value = rs.getLong(fieldname); + value = rs.getDouble(fieldname); if (rs.wasNull()) { - value = null; + isNull = true; } return true; } @@ -24,7 +25,14 @@ public String serialize(DBTable tbl) throws Exception { @Override public void deserialize(String data) throws Exception { - this.value = (data == null) ? null : Long.decode(data); + if (data == null) { + isNull = true; + value = 0; + } else { + isNull = false; + value = Double.parseDouble(data); + } + //this.value = (data == null) ? null : Long.decode(data); //this.value = Long.decode(data); /* try { @@ -37,14 +45,14 @@ public void deserialize(String data) throws Exception { @Override public String convertToString() { - return value != null ? value.toString() : null; + return !isNull ? String.valueOf(value) : null; } - public Long getValue() { + public double getValue() { return value; } - public void setValue(Long value) { + public void setValue(double value) { this.value = value; } @@ -62,7 +70,10 @@ public int removeFromGit() { @Override public String getSQLData() { - return (value == null) ? "''" : "\'"+value.toString()+"\'"; + return (isNull) ? "''" : "\'"+String.valueOf(value)+"\'"; + } + + public boolean isNull() { + return isNull; } - } diff --git a/src/main/java/ru/fusionsoft/dbgit/data_table/MapFileData.java b/src/main/java/ru/fusionsoft/dbgit/data_table/MapFileData.java index 32f6b1d..d127076 100644 --- a/src/main/java/ru/fusionsoft/dbgit/data_table/MapFileData.java +++ b/src/main/java/ru/fusionsoft/dbgit/data_table/MapFileData.java @@ -5,6 +5,8 @@ import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.sql.ResultSet; +import java.util.HashSet; +import java.util.Set; import ru.fusionsoft.dbgit.core.DBGit; import ru.fusionsoft.dbgit.core.DBGitLang; @@ -18,7 +20,10 @@ public class MapFileData implements ICellData { private String srcFile = null; private File tmpFile = null; - private String hash = null; + private static Set filesNotFound = new HashSet<>(); + private static int messageLevel = 2; + + //private String hash = null; public InputStream getBlobData(ResultSet rs, String fieldname) throws Exception { return rs.getBinaryStream(fieldname); @@ -44,7 +49,10 @@ public String serialize(DBTable tbl) throws Exception { DBGitPath.createDir(wrtFile.getAbsolutePath()); Files.move(tmpFile.toPath(), wrtFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "dataTable", "writeData").withParams(srcFile)); + ConsoleWriter.println(DBGitLang.getInstance().getValue("general", "dataTable", "writeData") + .withParams(srcFile) + , messageLevel + ); tmpFile = null; } return srcFile; @@ -52,9 +60,15 @@ public String serialize(DBTable tbl) throws Exception { @Override public void deserialize(String data) throws Exception { - File fp = new File(DBGitPath.getFullPath()+"/"+data); - if (fp.exists()) { - this.srcFile = data; + if(data != null){ + File fp = new File(DBGitPath.getFullPath()+"/"+data); + if (fp.exists()) { + this.srcFile = data; + } else { + int lastIndex = data.lastIndexOf('/'); + lastIndex = lastIndex == 0 ? data.lastIndexOf('\\') : lastIndex; + filesNotFound.add(data.substring(0, lastIndex)); + } } } @@ -68,17 +82,18 @@ public Object getWriterForRapair() { } public String getHash() throws Exception { - if (hash == null) { + //if (hash == null) { + String hash; String path = null; if (tmpFile != null) path = tmpFile.getAbsolutePath(); if (srcFile != null) path = DBGitPath.getFullPath()+"/"+srcFile; if (path == null) return ""; - + CalcHash ch = new CalcHash(); ch.addDataFile(path); hash = ch.calcHashStr(); - } + //} return hash; } @@ -110,6 +125,10 @@ public String getSQLData() { public File getFile() throws ExceptionDBGit { return new File(DBGitPath.getFullPath() + srcFile); } + + public static Set getFilesNotFound(){ + return filesNotFound; + } } 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 eb68e56..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,125 +1,194 @@ -package ru.fusionsoft.dbgit.data_table; - -import java.io.IOException; -import java.sql.ResultSet; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -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<>(); - protected String hashRow; - protected String key; - protected MetaTable metaTable; - - public RowData(ResultSet rs, MetaTable metaTable) throws Exception { - this.metaTable = metaTable; - loadDataFromRS(rs); - } - - public RowData(CSVRecord record, MetaTable metaTable, CSVRecord titleColumns) throws Exception { - this.metaTable = metaTable; - loadDataFromCSVRecord(record, titleColumns); - } - - public void loadDataFromRS(ResultSet rs) 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))) - data.put(columnName, cd); - } - - hashRow = calcRowHash(); - - key = calcRowKey(metaTable.getIdColumns()); - } - - public void loadDataFromCSVRecord(CSVRecord record, CSVRecord titleColumns) 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)); - - data.put(columnName, cd); - } - hashRow = calcRowHash(); - - key = calcRowKey(metaTable.getIdColumns()); - } - - public void saveDataToCsv(CSVPrinter csvPrinter, DBTable tbl) throws Exception { - for (ICellData cd : getData().values()) - 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 calcRowHash() throws Exception { - CalcHash ch = new CalcHash(); - for (ICellData cd : data.values()) { - String str = cd.convertToString(); - if ( str != null) - ch.addData(str); - } - return ch.calcHashStr(); - } - - public Map getData() { - return data; - } - - public String getHashRow() { - return hashRow; - } - - public String getKey() { - return key; - } - - public MetaTable getMetaTable() { - return metaTable; - } - - -} +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/DBCode.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBCode.java index beb735d..da9597e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBCode.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBCode.java @@ -1,6 +1,8 @@ package ru.fusionsoft.dbgit.dbobjects; -import ru.fusionsoft.dbgit.meta.DBGitMetaType; +import ru.fusionsoft.dbgit.utils.StringProperties; + +import java.util.Set; /** * Base class for all Objects BD with code style @@ -8,17 +10,10 @@ * */ public class DBCode extends DBSQLObject { - /* - private DBGitMetaType type; //pkg, fun, prc, trg - - public DBGitMetaType getType() { - return type; - } + public DBCode() { + } - public void setType(DBGitMetaType type) { - this.type = type; - } - - */ - + public DBCode(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/DBConstraint.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBConstraint.java index 4eebd98..6ba5390 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBConstraint.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBConstraint.java @@ -1,12 +1,24 @@ package ru.fusionsoft.dbgit.dbobjects; import ru.fusionsoft.dbgit.utils.CalcHash; +import ru.fusionsoft.dbgit.utils.StringProperties; +import ru.fusionsoft.dbgit.yaml.YamlOrder; import java.util.Objects; +import java.util.Set; public class DBConstraint extends DBSQLObject { + + @YamlOrder(4) private String constraintType; - + + public DBConstraint() { } + public DBConstraint(String name, StringProperties options, String schema, String owner, Set dependencies, String sql, String constraintType) { + super(name, options, schema, owner, dependencies, sql); + this.constraintType = constraintType; + } + + public String getConstraintType() { return constraintType; } @@ -14,26 +26,4 @@ public void setConstraintType(String constraintType) { this.constraintType = constraintType; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - DBConstraint that = (DBConstraint) o; - return Objects.equals(constraintType, that.constraintType) - && getName().equalsIgnoreCase(that.getName()) - && getSchema().equalsIgnoreCase(that.getSchema()) - && getSql().replaceAll("\\s+", "").equalsIgnoreCase(that.getSql().replaceAll("\\s+", "")); -// && getOptions().get("tablespace").getData().equalsIgnoreCase(that.getOptions().get("tablespace").getData()); - } - - public String getHash() { - CalcHash ch = new CalcHash(); - ch.addData(getSchema()); - ch.addData(getName()); - ch.addData(getSql().replaceAll("\\s+", "").toLowerCase()); - //TODO !!! - - return ch.calcHashStr(); - } - } 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/DBFunction.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBFunction.java index 0f11f51..c257530 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBFunction.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBFunction.java @@ -1,15 +1,13 @@ package ru.fusionsoft.dbgit.dbobjects; + import ru.fusionsoft.dbgit.utils.StringProperties; +import java.util.Set; + public class DBFunction extends DBCode { - - public DBFunction() { - - } - public DBFunction(String name) { - super(); - this.name = name; + public DBFunction() { } + public DBFunction(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/DBIndex.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBIndex.java index 32ada71..96941ad 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBIndex.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBIndex.java @@ -3,36 +3,14 @@ import ru.fusionsoft.dbgit.utils.CalcHash; import ru.fusionsoft.dbgit.utils.StringProperties; -public class DBIndex extends DBSQLObject { - //private DBTable table; - private StringProperties options = new StringProperties(); - public DBIndex() { - super(); - } - public DBIndex(String name) { - super(); - this.name = name; - } - +import java.util.Set; - public StringProperties getOptions() { - return options; - } +public class DBIndex extends DBSQLObject { - public void setOptions(StringProperties options) { - this.options = options; - } + public DBIndex() { - public String getSql() { - return options.get("ddl") != null ? options.get("ddl").toString() : ""; } - - public String getHash() { - CalcHash ch = new CalcHash(); - ch.addData(getSchema()); - ch.addData(getName()); - ch.addData(getSql().replaceAll("\\s+", "").toLowerCase()); - return ch.calcHashStr(); + public DBIndex(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/DBOptionsObject.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBOptionsObject.java index eb6d57a..ab9106b 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBOptionsObject.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBOptionsObject.java @@ -2,43 +2,64 @@ import ru.fusionsoft.dbgit.utils.CalcHash; import ru.fusionsoft.dbgit.utils.StringProperties; +import ru.fusionsoft.dbgit.yaml.YamlOrder; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; public class DBOptionsObject implements IDBObject { - private String name; - private StringProperties options = new StringProperties(); - - public DBOptionsObject() {} + + @YamlOrder(0) + String name; + + @YamlOrder(99) + StringProperties options; public DBOptionsObject(String name) { - this.setName(name); + this.name = name; + this.options = new StringProperties(); } - public DBOptionsObject(String name, StringProperties options) { - this.setName(name); - this.setOptions(options); + this.name = name; + this.options = options; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof DBOptionsObject)) return false; + + DBOptionsObject that = (DBOptionsObject) o; + return this.getHash().equals(that.getHash()); + } + + @Override + public int hashCode() { + return Objects.hash(getHash()); } - + + public String getHash() { + CalcHash ch = new CalcHash(); + ch.addData(this.name); + ch.addData(this.options.toString()); + + return ch.calcHashStr(); + } + public StringProperties getOptions() { return options; } - public void setOptions(StringProperties opt) { options = opt; } - public String getName() { return name; } - public void setName(String name) { this.name = name; } - public String getHash() { - CalcHash ch = new CalcHash(); - ch.addData(this.getName()); - ch.addData(this.getOptions().toString()); - return ch.calcHashStr(); - } } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBPackage.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBPackage.java index 0a657c5..d5b5ee3 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBPackage.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBPackage.java @@ -1,12 +1,13 @@ package ru.fusionsoft.dbgit.dbobjects; +import ru.fusionsoft.dbgit.utils.StringProperties; + +import java.util.Set; + public class DBPackage extends DBCode { - public DBPackage() { } - - public DBPackage(String name) { - super(); - this.name = name; - } - + public DBPackage() { } + public DBPackage(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/DBProcedure.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBProcedure.java index 9865343..d4b9767 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBProcedure.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBProcedure.java @@ -1,11 +1,13 @@ package ru.fusionsoft.dbgit.dbobjects; +import ru.fusionsoft.dbgit.utils.StringProperties; + +import java.util.Set; + public class DBProcedure extends DBCode { public DBProcedure() { } - - public DBProcedure(String name) { - super(); - this.name = name; + public DBProcedure(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/DBRole.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBRole.java index c31eff4..196d46d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBRole.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBRole.java @@ -1,10 +1,10 @@ package ru.fusionsoft.dbgit.dbobjects; +import ru.fusionsoft.dbgit.utils.StringProperties; + public class DBRole extends DBOptionsObject { - public DBRole() {} - public DBRole(String name) { - super(name); + public DBRole(String name, StringProperties options) { + super(name, options); } - } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSQLObject.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSQLObject.java index 6305c8f..48e4309 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSQLObject.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSQLObject.java @@ -1,10 +1,9 @@ package ru.fusionsoft.dbgit.dbobjects; +import java.util.Collections; import ru.fusionsoft.dbgit.utils.CalcHash; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.StringProperties; -import java.util.HashSet; import java.util.Set; /** @@ -15,38 +14,33 @@ public class DBSQLObject extends DBSchemaObject { protected String sql; - protected String owner; - private StringProperties options = new StringProperties(); + + public DBSQLObject() { + super("", new StringProperties(), "", "", Collections.emptySet()); + } + + public DBSQLObject(String name, StringProperties options, String schema, String owner, Set dependencies, String sql) { + super(name, options, schema, owner, dependencies); + this.sql = sql; + } public String getHash() { CalcHash ch = new CalcHash(); - ch.addData(getSchema()); - ch.addData(getName()); - ch.addData(getSql().trim().replaceAll("\\s+", "")); - if (getOwner() != null) - ch.addData(getOwner()); + + ch.addData(this.name); + ch.addData(this.schema); + ch.addData(this.owner); + ch.addData(this.options.toString()); + ch.addData(this.sql); return ch.calcHashStr(); } public String getSql() { - return options.get("ddl") != null ? options.get("ddl").toString() : ""; - } - public void setSql(String ddl) { if(options.get("ddl") != null) options.get("ddl").setData(ddl); } - - public String getOwner() { - return owner; - } - - public void setOwner(String owner) { - this.owner=owner; + return this.sql; } - public StringProperties getOptions() { - return options; - } - - public void setOptions(StringProperties options) { - this.options = options; + public void setSql(String ddl) { + this.sql = ddl; } } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSchema.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSchema.java index d8b444f..18ace79 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSchema.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSchema.java @@ -1,11 +1,13 @@ package ru.fusionsoft.dbgit.dbobjects; +import ru.fusionsoft.dbgit.utils.StringProperties; + public class DBSchema extends DBOptionsObject { - public DBSchema() { - super(""); + public DBSchema(String name, StringProperties options) { + super(name, options); } - + public DBSchema(String name) { super(name); } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSchemaObject.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSchemaObject.java index c01c5a8..16caad4 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSchemaObject.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSchemaObject.java @@ -1,6 +1,10 @@ package ru.fusionsoft.dbgit.dbobjects; +import java.util.Collections; +import ru.fusionsoft.dbgit.utils.StringProperties; +import ru.fusionsoft.dbgit.yaml.YamlOrder; + import java.util.HashSet; import java.util.Set; @@ -9,17 +13,25 @@ * @author mikle * */ -public abstract class DBSchemaObject implements IDBObject { - protected String name; +public abstract class DBSchemaObject extends DBOptionsObject { + + @YamlOrder(1) protected String schema; - private Set dependencies = new HashSet<>(); - - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; + + @YamlOrder(2) + protected String owner; + + @YamlOrder(3) + private Set dependencies; + + + public DBSchemaObject(String name, StringProperties options, String schema, String owner, Set dependencies) { + super(name, options); + this.schema = schema; + this.owner = owner == null ? "" : owner; + this.dependencies = dependencies == null ? Collections.emptySet() : dependencies; } + public String getSchema() { return schema; } @@ -33,5 +45,12 @@ public Set getDependencies() { public void setDependencies(Set dependencies) { this.dependencies = dependencies; } + + public String getOwner() { + return owner; + } + public void setOwner(String owner) { + this.owner=owner; + } } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSequence.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSequence.java index 93aa73a..1fee320 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSequence.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBSequence.java @@ -1,41 +1,48 @@ package ru.fusionsoft.dbgit.dbobjects; +import java.util.Collections; import ru.fusionsoft.dbgit.utils.CalcHash; import ru.fusionsoft.dbgit.utils.StringProperties; +import java.util.Set; + public class DBSequence extends DBSchemaObject { protected Long value; - private StringProperties options = new StringProperties(); - - public DBSequence() { } - - public DBSequence(String name) { this.name = name; } - public Long getValue() { - return value; + public DBSequence(){ + super("", new StringProperties(), "", "", Collections.emptySet()); } - - public void setValue(Long value) { + public DBSequence(String name, StringProperties options, String schema, String owner, Set dependencies, Long value) { + super(name, options, schema, owner, dependencies); this.value = value; } - - public StringProperties getOptions() { - return options; - } - - public void setOptions(StringProperties options) { - this.options = options; + + public StringProperties persistentOptions() { + //Immutable, yeah + StringProperties props = new StringProperties(getOptions().getData()); + props.setChildren(getOptions().getChildren()); + props.deleteChild("blocking_table"); + return props; } - + @Override public String getHash() { - + CalcHash ch = new CalcHash(); - ch.addData(getSchema()); - ch.addData(getName()); - ch.addData(getOptions().toString()); - ch.addData(getValue().toString()); + ch.addData(this.schema); + ch.addData(this.name); + ch.addData(this.owner); + ch.addData(persistentOptions().toString()); + ch.addData(String.valueOf(this.value)); return ch.calcHashStr(); } + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTable.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTable.java index 36beb5a..78e7778 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTable.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTable.java @@ -1,45 +1,101 @@ package ru.fusionsoft.dbgit.dbobjects; +import ru.fusionsoft.dbgit.core.NotImplementedExceptionDBGitRuntime; import ru.fusionsoft.dbgit.utils.CalcHash; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.StringProperties; +import ru.fusionsoft.dbgit.yaml.YamlOrder; + +import java.util.Collections; +import java.util.Set; public class DBTable extends DBSchemaObject { - private StringProperties options = new StringProperties(); - private String comment = ""; - public DBTable() { - super(); - } + @YamlOrder(4) + private String comment; - public DBTable(String name) { - super(); - this.name = name; + public DBTable() { + super("", new StringProperties(), "", "", Collections.emptySet()); } - public StringProperties getOptions() { - return options; + public DBTable(String name, StringProperties options, String schema, String owner, Set dependencies, String comment) { + super(name, options, schema, owner, dependencies); + this.comment = comment == null ? "" : comment; } - public void setOptions(StringProperties options) { - this.options = options; - } - public String getHash() { - CalcHash ch = new CalcHash(); - ch.addData(this.getName()); - ch.addData(this.getOptions().toString().replaceAll("\\s+", "")); - + CalcHash ch = new CalcHash()/*{ + public CalcHash addData(String str){ + ConsoleWriter.detailsPrintlnRed(str); + return super.addData(str); + } + }*/; + ch.addData(this.name); + ch.addData(this.schema); + ch.addData(this.owner); + ch.addData(this.options.toString()); + ch.addData(this.comment); return ch.calcHashStr(); } public void setComment(String comment) { - this.comment = comment; + this.comment = comment == null ? "" : comment; } public String getComment() { return this.comment; } + public static class OnlyNameDBTable extends DBTable{ + + public OnlyNameDBTable(String name, String schema) { + super(name, new StringProperties(), schema, "", Collections.emptySet(), ""); + } + + @Override + public String getHash() { + throw new NotImplementedExceptionDBGitRuntime(); + } + + @Override + public void setComment(String comment) { + throw new NotImplementedExceptionDBGitRuntime(); + } + + @Override + public String getComment() { + throw new NotImplementedExceptionDBGitRuntime(); + } + + @Override + public Set getDependencies() { + throw new NotImplementedExceptionDBGitRuntime(); + } + + @Override + public void setDependencies(Set dependencies) { + throw new NotImplementedExceptionDBGitRuntime(); + } + + @Override + public String getOwner() { + throw new NotImplementedExceptionDBGitRuntime(); + } + + @Override + public void setOwner(String owner) { + throw new NotImplementedExceptionDBGitRuntime(); + } + + @Override + public StringProperties getOptions() { + throw new NotImplementedExceptionDBGitRuntime(); + } + + @Override + public void setOptions(StringProperties opt) { + throw new NotImplementedExceptionDBGitRuntime(); + } + } + } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableData.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableData.java index 6d4fedd..affce1d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableData.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableData.java @@ -1,30 +1,58 @@ package ru.fusionsoft.dbgit.dbobjects; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; +import ru.fusionsoft.dbgit.core.ExceptionDBGitTableData; + +import java.io.Closeable; +import java.sql.Connection; import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; -public class DBTableData { +public class DBTableData implements AutoCloseable, Closeable { public static final int ERROR_LIMIT_ROWS = 1; - protected int errorFlag = 0; - protected ResultSet resultSet; - - public int getErrorFlag() { - return errorFlag; - } + final protected int errorFlag ; + final protected ResultSet resultSet; + final protected Statement statement; - public void setErrorFlag(int errorFlag) { + public DBTableData(Connection connection, String query) throws SQLException { + this.errorFlag = 0; + this.statement = connection.createStatement(); + this.resultSet = statement.executeQuery(query); + } + public DBTableData(int errorFlag) { this.errorFlag = errorFlag; + this.resultSet = null; + this.statement = null; } - + public int errorFlag() { + return errorFlag; + } + public ResultSet resultSet() throws ExceptionDBGitTableData { - public ResultSet getResultSet() { return resultSet; +// TODO find usages and adapt to recover from the ExceptionDBGitTableData +// if(resultSet != null){ +// return resultSet; +// } else { +// final String msg = DBGitLang.getInstance() +// .getValue("errors", "dataTable", "errorTableData") +// .withParams(String.valueOf(errorFlag)); +// +// throw new ExceptionDBGitTableData(msg, errorFlag); +// } } - public void setResultSet(ResultSet resultSet) { - this.resultSet = resultSet; + + @Override + public void close() { + try{ + this.resultSet.close(); + this.statement.close(); + } catch (SQLException ex){ + throw new ExceptionDBGitRunTime(ex); + } } - - -} +} \ No newline at end of file diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableField.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableField.java index e60bd5d..7343a20 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableField.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableField.java @@ -2,83 +2,127 @@ import ru.fusionsoft.dbgit.core.db.FieldType; import ru.fusionsoft.dbgit.utils.CalcHash; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; +import ru.fusionsoft.dbgit.yaml.YamlOrder; + +import java.nio.channels.IllegalSelectorException; +import java.util.Objects; public class DBTableField implements IDBObject, Comparable { - private String name; - private String description; - private String typeSQL; - private FieldType typeUniversal; - private int length; - private int scale; - private int precision; - private boolean fixed; - private Integer order = 0; - private Boolean isNullable; - private Boolean isNameExactly = false; - private String defaultValue; - + + @YamlOrder(0) + private String name = ""; + @YamlOrder(1) + private String description = ""; + @YamlOrder(2) private Boolean isPrimaryKey = false; + @YamlOrder(3) + private Boolean isNullable = false; + @YamlOrder(4) + private String typeSQL = ""; + @YamlOrder(5) + private FieldType typeUniversal = FieldType.UNDEFINED; + @YamlOrder(6) + private Integer order = -1; + @YamlOrder(7) + private String defaultValue = ""; + @YamlOrder(8) + private int length = 0; + @YamlOrder(9) + private int scale = 0; + @YamlOrder(10) + private int precision = 0; + @YamlOrder(11) + private boolean fixed = false; + + public DBTableField() { + //Just for things that want to introspect my guts and use setters + this.order = -1; + this.defaultValue = ""; + this.description = ""; + this.fixed = false; + this.isNullable = false; + this.isPrimaryKey = false; + this.length = 0; + this.name = ""; + this.precision = 0; + this.scale = 0; + this.typeSQL = ""; + this.typeUniversal = FieldType.UNDEFINED; + } + + public DBTableField(String name, String description, Boolean isPrimaryKey, Boolean isNullable, String typeSQL, FieldType typeUniversal, Integer order, String defaultValue, int length, int scale, int precision, boolean fixed) { + this.name = name; + this.description = description == null ? "" : description; + this.isPrimaryKey = isPrimaryKey; + this.isNullable = isNullable; + this.typeSQL = typeSQL; + this.typeUniversal = typeUniversal; + this.order = order; + this.defaultValue = defaultValue == null ? "" : defaultValue; + this.length = length; + this.scale = scale; + this.precision = precision; + this.fixed = fixed; + } - public Boolean getIsPrimaryKey() { - return isPrimaryKey; + @Override + public int compareTo(DBTableField o) { + int res = - isPrimaryKey.compareTo(o.getIsPrimaryKey()); + if (res != 0) return res; + return order.compareTo(o.getOrder()); +// return name.compareTo(o.getName()); } - public void setIsPrimaryKey(Boolean isPrimaryKey) { - this.isPrimaryKey = isPrimaryKey; + @Override public boolean equals(Object obj){ + boolean equals = obj == this; + if(!equals && obj instanceof DBTableField){ + return ((DBTableField) obj).getHash().equals(this.getHash()); + } + return equals; + } + + @Override + public int hashCode() { + return Objects.hash(getHash()); } public String getHash() { CalcHash ch = new CalcHash(); - ch.addData(this.getName()); - ch.addData(this.getTypeSQL()); - if( this.getDefaultValue()!=null ) ch.addData(this.getDefaultValue()); -// if( this.getOrder()!=null ) ch.addData(String.valueOf(this.getOrder())); - ch.addData(isPrimaryKey.toString()); + + ch.addData(this.name); + ch.addData(this.typeSQL); + ch.addData(this.order); + ch.addData(this.isPrimaryKey); + ch.addData(this.isNullable); + ch.addData(this.description); + ch.addData(this.defaultValue); + ch.addData(this.fixed); + ch.addData(this.length); + ch.addData(this.precision); + ch.addData(this.scale); return ch.calcHashStr(); } - public Boolean getIsNullable() { return isNullable; } - - public void setIsNullable(Boolean isNullable) { this.isNullable = isNullable; } - public void setTypeUniversal(FieldType typeUniversal) { - this.typeUniversal = typeUniversal; + public Boolean getIsPrimaryKey() { + return isPrimaryKey; } - + + public Boolean getIsNullable() { return isNullable; } + public FieldType getTypeUniversal() { return typeUniversal; } - - public void setLength(int length) { - this.length = length; - } - - public int getLength() { - return length; - } - public void setScale(int scale) { - this.scale = scale; - } - - public int getScale() { - return scale; + public int getLength() { + return length; } - public void setPrecision(int precision) { - this.precision = precision; - } - public int getPrecision() { return precision; } - public void setFixed(boolean fixed) { - this.fixed = fixed; - } - public boolean getFixed() { return fixed; } @@ -87,56 +131,73 @@ public String getName() { return name; } - public void setName(String name) { - this.name = name; - } - public String getTypeSQL() { return typeSQL; } - public void setTypeSQL(String typeSQL) { - this.typeSQL = typeSQL; - } - - public void setOrder(Integer order) { - this.order = order; - } - public Integer getOrder() { return order; } - - public void setNameExactly(Boolean isNameExactly) { - this.isNameExactly = isNameExactly; - } - - public Boolean getNameExactly() { - return isNameExactly; - } - + public String getDefaultValue() { return this.defaultValue; } - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; + public int getScale() { + return scale; } public String getDescription() { return this.description; } - public void setDescription(String description) { - this.description = description; + public void setIsPrimaryKey(Boolean isPrimaryKey) { + this.isPrimaryKey = isPrimaryKey; } - - @Override - public int compareTo(DBTableField o) { - int res = - isPrimaryKey.compareTo(o.getIsPrimaryKey()); - if (res != 0) return res; - return name.compareTo(o.getName()); + + public void setTypeUniversal(FieldType typeUniversal) { + this.typeUniversal = typeUniversal == null ? FieldType.UNDEFINED : typeUniversal; + } + + public void setIsNullable(Boolean isNullable) { this.isNullable = isNullable; } + + public void setLength(int length) { + this.length = length; } + + public void setScale(int scale) { + this.scale = scale; + } + + public void setPrecision(int precision) { + this.precision = precision; + } + + public void setFixed(boolean fixed) { + this.fixed = fixed; + } + + public void setName(String name) { + this.name = name; + } + + public void setOrder(Integer order) { + this.order = order; + } + + public void setTypeSQL(String typeSQL) { + this.typeSQL = typeSQL; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue == null ? "" : defaultValue; + } + + public void setDescription(String description) { + this.description = description == null ? "" : description; + } + + } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableSpace.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableSpace.java index 7213cd9..b4c6b38 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableSpace.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTableSpace.java @@ -1,12 +1,10 @@ package ru.fusionsoft.dbgit.dbobjects; +import ru.fusionsoft.dbgit.utils.StringProperties; + public class DBTableSpace extends DBOptionsObject { - - public DBTableSpace() { - super(""); - } - - public DBTableSpace(String name) { - super(name); + + public DBTableSpace(String name, StringProperties options) { + super(name, options); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTrigger.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTrigger.java index 7c9aa09..d38c4f1 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTrigger.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBTrigger.java @@ -2,11 +2,12 @@ import ru.fusionsoft.dbgit.utils.StringProperties; +import java.util.Set; + public class DBTrigger extends DBCode { - public DBTrigger() { - - } - public DBTrigger(String name) { - this.name = name; + + public DBTrigger() { } + public DBTrigger(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/DBUser.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBUser.java index e27d3ed..90820ed 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBUser.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBUser.java @@ -3,11 +3,7 @@ import ru.fusionsoft.dbgit.utils.StringProperties; public class DBUser extends DBOptionsObject { - public DBUser() {} - - public DBUser(String name) { - super(name); + public DBUser(String name, StringProperties options) { + super(name, options); } - - public DBUser(String name, StringProperties options) { super(name, options); } } 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/dbobjects/DBView.java b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBView.java index e0ede68..a543ec4 100644 --- a/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBView.java +++ b/src/main/java/ru/fusionsoft/dbgit/dbobjects/DBView.java @@ -1,13 +1,13 @@ package ru.fusionsoft.dbgit.dbobjects; +import ru.fusionsoft.dbgit.utils.StringProperties; + +import java.util.Set; + public class DBView extends DBSQLObject { - public DBView(String name) { - super(); - this.name = name; + public DBView() { } + public DBView(String name, StringProperties options, String schema, String owner, Set dependencies, String sql) { + super(name, options, schema, owner, dependencies, sql); } - public DBView() { - super(); - } - } 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/IMetaObject.java b/src/main/java/ru/fusionsoft/dbgit/meta/IMetaObject.java index 379ebd7..7e5468b 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/IMetaObject.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/IMetaObject.java @@ -7,6 +7,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Constructor; +import java.util.Map; + import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.DBGitPath; @@ -34,7 +36,9 @@ */ public interface IMetaObject { public static final String EMPTY_HASH = ""; - public static final int MAX_FILE_NAME_LENGTH = 130; + public static final int MAX_FILE_NAME_LENGTH = 130; + public static int messageLevel = 1; + /** * * @return Type meta object @@ -55,7 +59,9 @@ public interface IMetaObject { public void setDbType(DbType dbType); public String getDbVersion(); - + + public Double getDbVersionNumber(); + public void setDbVersion(String dbVersion); public String getFileName(); @@ -78,45 +84,50 @@ public interface IMetaObject { * @throws IOException */ public IMetaObject deSerialize(InputStream stream) throws Exception; - + + public default IMetaObject deSerialize(File file) throws Exception { + return this; + }; + + public Map toMap(); + /** * load current object from DB */ public boolean loadFromDB() throws ExceptionDBGit; - + public String getHash(); - + /** * Save meta file to base path * Example - .dbgit/basePath/path_and_filename_meta_object - * + * * @param basePath * @throws IOException */ default boolean saveToFile(String basePath) throws ExceptionDBGit { File file = new File(DBGitPath.getFullPath(basePath)+"/"+getFileName()); DBGitPath.createDir(file.getParent()); - + try { FileOutputStream out = new FileOutputStream(file.getAbsolutePath()); boolean res = this.serialize(out); out.close(); - + return res; } catch (Exception e) { - e.printStackTrace(); throw new ExceptionDBGit(e); } } - + default boolean saveToFile() throws ExceptionDBGit { return saveToFile(null); } - + /** * Load meta file to base path * Example - .dbgit/basePath/path_and_filename_meta_object - * + * * @param basePath * @throws IOException */ @@ -124,7 +135,11 @@ default IMetaObject loadFromFile(String basePath) throws Exception { String filename = DBGitPath.getFullPath(basePath); File file = new File(filename+"/"+getFileName()); FileInputStream fis = new FileInputStream(file); - IMetaObject meta = this.deSerialize(fis); + IMetaObject meta; + if (!file.getPath().endsWith(".csv")) + meta = this.deSerialize(fis); + else + meta = this.deSerialize(file); fis.close(); if (meta != null && meta.getName().isEmpty()) { meta.setName(this.getName()); @@ -145,10 +160,16 @@ default IMetaObject loadFromFile() throws Exception { default DBSchemaObject getUnderlyingDbObject(){ //All in one place if(this instanceof MetaSql) return ((MetaSql) this).getSqlObject(); + if(this instanceof MetaSequence) return ((MetaSequence) this).getSequence(); if(this instanceof MetaTable) return ((MetaTable) this).getTable(); return null; } + default boolean dependsOn(IMetaObject obj){ + if (this.getUnderlyingDbObject() == null || this.getUnderlyingDbObject().getDependencies() == null) return false; + return this.getUnderlyingDbObject().getDependencies().contains(obj.getName()); + } + static IMetaObject create(String name) throws ExceptionDBGit { NameMeta nm = new NameMeta(name); if (nm.getType() == null) throw new ExceptionDBGit(DBGitLang.getInstance().getValue("errors", "meta", "parseError").withParams(name)); diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaBase.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaBase.java index 03d33e3..30d10cb 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaBase.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaBase.java @@ -1,137 +1,164 @@ -package ru.fusionsoft.dbgit.meta; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.Charset; - -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.DumperOptions.ScalarStyle; -import org.yaml.snakeyaml.nodes.Tag; - -import ru.fusionsoft.dbgit.adapters.AdapterFactory; -import ru.fusionsoft.dbgit.core.DBGit; -import ru.fusionsoft.dbgit.core.DBGitPath; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; -import ru.fusionsoft.dbgit.core.db.DbType; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; -import ru.fusionsoft.dbgit.yaml.DBGitYamlConstructor; -import ru.fusionsoft.dbgit.yaml.DBGitYamlRepresenter; -import ru.fusionsoft.dbgit.yaml.YamlOrder; - - -/** - * Base class for all meta objects - * @author mikle - * - */ -public abstract class MetaBase implements IMetaObject { - @YamlOrder(0) - protected String name; - - @YamlOrder(1) - protected DbType dbType; - - @YamlOrder(1) - protected String dbVersion; - - @Override - public String getName() { - return name; - } - - @Override - public void setDbType(DbType dbType) { - this.dbType = dbType; - } - - @Override - public DbType getDbType() { - return dbType; - } - - @Override - public void setDbVersion(String dbVersion) { - this.dbVersion = dbVersion; - } - - @Override - public String getDbVersion() { - return dbVersion; - } - - @Override - public void setName(String name) throws ExceptionDBGit { - this.name = name; - } - - @Override - public String getFileName() { - return getName(); - } - - /** - *
When you save the yaml object, the library ignores properties for which there is no getter and setter
- *
При сохранении объекта yaml библиотека игнорирует свойства для которых нет геттера и сеттера
- * @param stream - * @throws IOException - */ - public boolean yamlSerialize(OutputStream stream) throws IOException { - Yaml yaml = createYaml(); - String output = yaml.dumpAs(this, Tag.MAP, DumperOptions.FlowStyle.BLOCK); - - stream.write(output.getBytes(Charset.forName("UTF-8"))); - return true; - } - - public IMetaObject yamlDeSerialize(InputStream stream) { - Yaml yaml = createYaml(); - - IMetaObject meta = yaml.loadAs(stream, this.getClass()); - return meta; - } - - public Yaml createYaml() { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - options.setPrettyFlow(true); - Yaml yaml = new Yaml(new DBGitYamlConstructor(), new DBGitYamlRepresenter(), options); - return yaml; - } - - @Override - public int addToGit() throws ExceptionDBGit { - DBGit dbGit = DBGit.getInstance(); - dbGit.addFileToIndexGit(DBGitPath.DB_GIT_PATH+"/"+getFileName()); - return 1; - } - - @Override - public int removeFromGit() throws ExceptionDBGit { - DBGit dbGit = DBGit.getInstance(); - dbGit.removeFileFromIndexGit(DBGitPath.DB_GIT_PATH+"/"+getFileName()); - return 1; - } - - public void setDbType() { - try { - setDbType(AdapterFactory.createAdapter().getDbType()); - } catch (ExceptionDBGit e) { - throw new ExceptionDBGitRunTime(e.getLocalizedMessage()); - } - - } - - public void setDbVersion() { - try { - setDbVersion(AdapterFactory.createAdapter().getDbVersion()); - } catch (ExceptionDBGit e) { - throw new ExceptionDBGitRunTime(e.getLocalizedMessage()); - } - - } - - -} +package ru.fusionsoft.dbgit.meta; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.nodes.Tag; + +import ru.fusionsoft.dbgit.adapters.AdapterFactory; +import ru.fusionsoft.dbgit.core.DBGit; +import ru.fusionsoft.dbgit.core.DBGitPath; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; +import ru.fusionsoft.dbgit.core.db.DbType; +import ru.fusionsoft.dbgit.utils.StringProperties; +import ru.fusionsoft.dbgit.yaml.DBGitYamlConstructor; +import ru.fusionsoft.dbgit.yaml.DBGitYamlRepresenter; +import ru.fusionsoft.dbgit.yaml.YamlOrder; + + +/** + * Base class for all meta objects + * @author mikle + * + */ +public abstract class MetaBase implements IMetaObject { + @YamlOrder(0) + protected String name; + + @YamlOrder(1) + protected DbType dbType; + + @YamlOrder(2) + protected String dbVersion; + + @Override + public String getName() { + return name; + } + + @Override + public void setDbType(DbType dbType) { + this.dbType = dbType; + } + + @Override + public DbType getDbType() { + return dbType; + } + + @Override + public void setDbVersion(String dbVersion) { + this.dbVersion = dbVersion; + } + + @Override + public String getDbVersion() { + return dbVersion; + } + + @Override + public Double getDbVersionNumber() { + Matcher matcher = Pattern.compile("\\D*(\\d+)\\.(\\d+)").matcher(getDbVersion()); + matcher.find(); + Double result = Double.valueOf(matcher.group(0)+matcher.group(1)); + return result; + } + + @Override + public void setName(String name) throws ExceptionDBGit { + this.name = name; + } + + @Override + public String getFileName() { + return getName(); + } + + /** + *
When you save the yaml object, the library ignores properties for which there is no getter and setter
+ *
При сохранении объекта yaml библиотека игнорирует свойства для которых нет геттера и сеттера
+ * @param stream + * @throws IOException + */ + public boolean yamlSerialize(OutputStream stream) throws IOException { + Yaml yaml = createYaml(); + String output = yaml.dumpAs(this, Tag.MAP, DumperOptions.FlowStyle.BLOCK); + + stream.write(output.getBytes(Charset.forName("UTF-8"))); + return true; + } + + public IMetaObject yamlDeSerialize(InputStream stream) { + Yaml yaml = createYaml(); + //Map some = yaml.loadAs(stream, Map.class); + IMetaObject meta = yaml.loadAs(stream, this.getClass()); + return meta; + } + + public Map toMap() { + Yaml yaml = createYaml(); + String output = yaml.dumpAs(this, Tag.MAP, DumperOptions.FlowStyle.BLOCK); + Map meta = yaml.loadAs(output, Map.class); + return meta; + } + + public Yaml createYaml() { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setPrettyFlow(true); + + Yaml yaml = new Yaml(new DBGitYamlConstructor(), new DBGitYamlRepresenter(), options); + return yaml; + } + + @Override + public int addToGit() throws ExceptionDBGit { + DBGit dbGit = DBGit.getInstance(); + dbGit.addFileToIndexGit(DBGitPath.DB_GIT_PATH+"/"+getFileName()); + return 1; + } + + @Override + public int removeFromGit() throws ExceptionDBGit { + DBGit dbGit = DBGit.getInstance(); + dbGit.removeFileFromIndexGit(DBGitPath.DB_GIT_PATH+"/"+getFileName()); + return 1; + } + + public void setDbType() { + try { + setDbType(AdapterFactory.createAdapter().getDbType()); + } catch (ExceptionDBGit e) { + throw new ExceptionDBGitRunTime(e.getLocalizedMessage()); + } + + } + + public void setDbVersion() { + try { + setDbVersion(AdapterFactory.createAdapter().getDbVersion()); + } catch (ExceptionDBGit e) { + throw new ExceptionDBGitRunTime(e.getLocalizedMessage()); + } + + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof MetaBase)) return false; + MetaBase metaBase = (MetaBase) o; + return getHash().equals(metaBase.getHash()); + } + + @Override + public int hashCode() { + return getHash().hashCode(); + } +} 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/MetaFunction.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaFunction.java index 9823362..09d6a0e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaFunction.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaFunction.java @@ -11,7 +11,7 @@ public class MetaFunction extends MetaSql { public MetaFunction() { super(); } - + public MetaFunction(DBFunction fun) throws ExceptionDBGit { super(fun); } @@ -21,14 +21,12 @@ public DBGitMetaType getType() { return DBGitMetaType.DbGitFunction; } - @Override - public String getName() { - return name; - } - @Override public String getFileName(){ String res = name.replace(".fnc", ""); + String schemaName = ""; + if (res.contains("/")) + schemaName = res.substring(0, res.indexOf("/")); if (this.getSqlObject() != null && this.getSqlObject().getOptions() != null && this.getSqlObject().getOptions().get("arguments") != null) res = res + "_" + this.getSqlObject().getOptions().get("arguments").getData() @@ -41,7 +39,7 @@ public String getFileName(){ .replace("::", ""); if (res.endsWith("_")) res = res.substring(0, res.length() - 1); - if (res.length() > MAX_FILE_NAME_LENGTH) { + if (res.length() > (schemaName.length() + 1 + MAX_FILE_NAME_LENGTH)) { String resTemp = res.substring(0, MAX_FILE_NAME_LENGTH); int resInt = res.length() - MAX_FILE_NAME_LENGTH; res = resTemp + "_" + resInt; @@ -51,7 +49,7 @@ public String getFileName(){ return res; } - + @Override public boolean loadFromDB() throws ExceptionDBGit { IDBAdapter adapter = AdapterFactory.createAdapter(); diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaObjOptions.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaObjOptions.java index 8063e44..d4f5d8b 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaObjOptions.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaObjOptions.java @@ -4,15 +4,14 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Map; +import java.util.Objects; -import ru.fusionsoft.dbgit.adapters.AdapterFactory; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.core.ExceptionDBGitObjectNotFound; import ru.fusionsoft.dbgit.dbobjects.DBOptionsObject; -import ru.fusionsoft.dbgit.dbobjects.DBUser; import ru.fusionsoft.dbgit.utils.CalcHash; +import ru.fusionsoft.dbgit.yaml.YamlOrder; /** * Base Meta class for data use DBOptionsObject information. This data is tree string properties. @@ -21,6 +20,7 @@ */ public abstract class MetaObjOptions extends MetaBase { + @YamlOrder(4) private DBOptionsObject objectOption = null; public MetaObjOptions() { @@ -48,7 +48,7 @@ public boolean serialize(OutputStream stream) throws IOException { } @Override - public IMetaObject deSerialize(InputStream stream) throws IOException{ + public IMetaObject deSerialize(InputStream stream) { return yamlDeSerialize(stream); } @@ -75,4 +75,16 @@ public void setObjectOptionFromMap(Map map) t setObjectOption(map.get(nm.getName())); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof MetaObjOptions)) return false; + MetaObjOptions that = (MetaObjOptions) o; + return getObjectOption().getHash().equals(that.getObjectOption().getHash()); + } + + @Override + public int hashCode() { + return Objects.hash(getObjectOption()); + } } diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaObjectFactory.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaObjectFactory.java index ca303bd..0beb554 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaObjectFactory.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaObjectFactory.java @@ -46,21 +46,18 @@ public static IMetaObject createMetaObject(IDBGitMetaType tp) throws ExceptionDB } - public static NameMeta parseMetaName(String name) throws ExceptionDBGit { - try { - NameMeta nm = new NameMeta(); - - Integer pos = name.lastIndexOf("/"); - if (pos > 0) { - nm.setSchema(name.substring(0, pos)); - } - Integer posDot = name.lastIndexOf("."); - nm.setName(name.substring(pos+1, posDot)); - nm.setType(DBGitMetaType.valueByCode(name.substring(posDot + 1))); + public static NameMeta parseMetaName(String name) { + NameMeta nm = new NameMeta(); - return nm; - } catch(Exception e) { - throw new ExceptionDBGitRunTime(DBGitLang.getInstance().getValue("errors", "meta", "parseError").withParams(name), e); + Integer pos = name.lastIndexOf("/"); + if (pos > 0) { + nm.setSchema(name.substring(0, pos)); } + Integer posDot = name.lastIndexOf("."); + nm.setName(name.substring(pos+1, posDot)); + nm.setType(DBGitMetaType.valueByCode(name.substring(posDot + 1))); + + return nm; + } } diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaProcedure.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaProcedure.java index 7335917..46a8a61 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaProcedure.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaProcedure.java @@ -29,6 +29,9 @@ public String getName() { @Override public String getFileName(){ String res = name.replace(".prc", ""); + String schemaName = ""; + if (res.contains("/")) + schemaName = res.substring(0, res.indexOf("/")); if (this.getSqlObject() != null && this.getSqlObject().getOptions() != null && this.getSqlObject().getOptions().get("arguments") != null) res = res + "_" + this.getSqlObject().getOptions().get("arguments").getData() @@ -41,7 +44,7 @@ public String getFileName(){ .replace("::", ""); if (res.endsWith("_")) res = res.substring(0, res.length() - 1); - if (res.length() > MAX_FILE_NAME_LENGTH) { + if (res.length() > (schemaName.length() + 1 + MAX_FILE_NAME_LENGTH)) { String resTemp = res.substring(0, MAX_FILE_NAME_LENGTH); int resInt = res.length() - MAX_FILE_NAME_LENGTH; res = resTemp + "_" + resInt; diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaSql.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaSql.java index 78667f9..7319170 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaSql.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaSql.java @@ -1,18 +1,10 @@ package ru.fusionsoft.dbgit.meta; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.StringWriter; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import org.apache.commons.io.IOUtils; - -import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitObjectNotFound; -import ru.fusionsoft.dbgit.dbobjects.DBOptionsObject; import ru.fusionsoft.dbgit.dbobjects.DBSQLObject; /** @@ -21,19 +13,18 @@ * */ public abstract class MetaSql extends MetaBase { - - + protected DBSQLObject sqlObject; public MetaSql() { setDbType(); setDbVersion(); } - + public MetaSql(DBSQLObject sqlObject) throws ExceptionDBGit { this(); setSqlObject(sqlObject); - } - + } + public DBSQLObject getSqlObject() { return sqlObject; } @@ -45,7 +36,7 @@ public void setSqlObject(DBSQLObject sqlObject) throws ExceptionDBGit { } @Override - public boolean serialize(OutputStream stream) throws Exception { + public boolean serialize(OutputStream stream) throws IOException { /* String owner = "owner: "+getSqlObject().getOwner()+"\n"; stream.write(owner.getBytes(Charset.forName("UTF-8"))); @@ -59,7 +50,7 @@ public boolean serialize(OutputStream stream) throws Exception { } @Override - public IMetaObject deSerialize(InputStream stream) throws Exception { + public IMetaObject deSerialize(InputStream stream) { NameMeta nm = MetaObjectFactory.parseMetaName(getName()); /* sqlObject = new DBSQLObject(); @@ -83,12 +74,13 @@ public IMetaObject deSerialize(InputStream stream) throws Exception { public String getHash() { return sqlObject != null ? sqlObject.getHash() : EMPTY_HASH; } - public void setObjectOptionFromMap(Map map) throws ExceptionDBGit { - NameMeta nm = MetaObjectFactory.parseMetaName(getName()); - if (!map.containsKey(nm.getName())) { - throw new ExceptionDBGitObjectNotFound(DBGitLang.getInstance().getValue("errors", "meta", "notFound").withParams(getName())); - } - setSqlObject(map.get(nm.getName())); - } + +// public void setSqlObjectFromMap(Map map) throws ExceptionDBGit { +// NameMeta nm = MetaObjectFactory.parseMetaName(getName()); +// if (!map.containsKey(nm.getName())) { +// throw new ExceptionDBGitObjectNotFound(DBGitLang.getInstance().getValue("errors", "meta", "notFound").withParams(getName())); +// } +// setSqlObject(map.get(nm.getName())); +// } } diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaTable.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaTable.java index 96bbcb1..927a338 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaTable.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaTable.java @@ -11,55 +11,49 @@ import ru.fusionsoft.dbgit.adapters.IDBAdapter; import ru.fusionsoft.dbgit.core.DBGitIndex; import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; -import ru.fusionsoft.dbgit.core.ItemIndex; -import ru.fusionsoft.dbgit.dbobjects.DBConstraint; -import ru.fusionsoft.dbgit.dbobjects.DBIndex; -import ru.fusionsoft.dbgit.dbobjects.DBSchema; -import ru.fusionsoft.dbgit.dbobjects.DBTable; -import ru.fusionsoft.dbgit.dbobjects.DBTableField; +import ru.fusionsoft.dbgit.core.ExceptionDBGitObjectNotFound; +import ru.fusionsoft.dbgit.dbobjects.*; import ru.fusionsoft.dbgit.utils.CalcHash; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.yaml.YamlOrder; /** - * Meta class for db Table + * Meta class for db Table * @author mikle * */ -public class MetaTable extends MetaBase { +public class MetaTable extends MetaBase { - @YamlOrder(1) + @YamlOrder(3) private DBTable table; - - @YamlOrder(2) + + @YamlOrder(4) //private IMapFields fields = new TreeMapFields(); private Map fields = new TreeMap<>(); - - @YamlOrder(3) + + @YamlOrder(5) private Map indexes = new TreeMap<>(); - - @YamlOrder(4) + + @YamlOrder(6) private Map constraints = new TreeMap<>(); - public MetaTable() { + public MetaTable() { setDbType(); setDbVersion(); } - + public MetaTable(String namePath) { setDbType(); setDbVersion(); this.name = namePath; } - + public MetaTable(DBTable tbl) { setDbType(); setDbVersion(); setTable(tbl); } - + @Override public DBGitMetaType getType() { return DBGitMetaType.DBGitTable; @@ -71,7 +65,7 @@ public boolean serialize(OutputStream stream) throws IOException { } @Override - public IMetaObject deSerialize(InputStream stream) throws IOException { + public IMetaObject deSerialize(InputStream stream) { return yamlDeSerialize(stream); } @@ -79,12 +73,15 @@ public IMetaObject deSerialize(InputStream stream) throws IOException { public boolean loadFromDB() throws ExceptionDBGit { IDBAdapter adapter = AdapterFactory.createAdapter(); NameMeta nm = MetaObjectFactory.parseMetaName(getName()); - - DBTable tbl = adapter.getTable(nm.getSchema(), nm.getName()); - if (tbl != null) - return loadFromDB(tbl); - else + try { + DBTable tbl = adapter.getTable(nm.getSchema(), nm.getName()); + if (tbl != null) + return loadFromDB(tbl); + else + return false; + } catch (ExceptionDBGitObjectNotFound exnf) { return false; + } } public boolean loadFromDB(DBTable tbl) throws ExceptionDBGit { @@ -126,7 +123,13 @@ public boolean loadFromDB(DBTable tbl) throws ExceptionDBGit { @Override public String getHash() { - CalcHash ch = new CalcHash(); + CalcHash ch = new CalcHash()/*{ + @Override + public CalcHash addData(String str){ + ConsoleWriter.printlnRed(str); + return super.addData(str); + } + }*/; ch.addData(this.getName()); if (getTable() != null) { @@ -142,20 +145,17 @@ public String getHash() { } - if (indexes != null) { - for (String item : indexes.keySet()) { - ch.addData(item); - ch.addData(indexes.get(item).getHash()); + for (String item : indexes.keySet()) { + if(constraints.containsKey(item)) continue; + ch.addData(item); + ch.addData(indexes.get(item).getHash()); - } } - - if (constraints != null) { - for (String item : constraints.keySet()) { - ch.addData(item); - ch.addData(constraints.get(item).getHash()); - } + for (String item : constraints.keySet()) { + ch.addData(item); + ch.addData(constraints.get(item).getHash()); + } return ch.calcHashStr(); @@ -213,15 +213,27 @@ public void setConstraints(Map constraints) { this.constraints.putAll(constraints); } - public List getIdColumns() { - List idColumns = new ArrayList<>(); - + public List getIdColumns() { + List idColumns = new ArrayList<>(); + + int i = 0; for (DBTableField field : fields.values()) { if (field.getIsPrimaryKey()) { - idColumns.add(field.getName()); + //idColumns.add(field.getName()); + idColumns.add(i); } + i++; } return idColumns; } +// private String truncateHash(String hash){ +// return hash.substring( +// 0, +// 2 +// ) + hash.substring( +// hash.length() - 3, +// hash.length() - 1 +// ); +// } } diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/MetaTableData.java b/src/main/java/ru/fusionsoft/dbgit/meta/MetaTableData.java index 34f4400..fa3042d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/MetaTableData.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/MetaTableData.java @@ -1,374 +1,453 @@ -package ru.fusionsoft.dbgit.meta; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.nio.charset.Charset; -import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVParser; -import org.apache.commons.csv.CSVPrinter; -import org.apache.commons.csv.CSVRecord; -import org.apache.commons.csv.QuoteMode; - -import com.diogonunes.jcdp.color.api.Ansi.FColor; - -import ru.fusionsoft.dbgit.adapters.AdapterFactory; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.DBGit; -import ru.fusionsoft.dbgit.core.DBGitConfig; -import ru.fusionsoft.dbgit.core.DBGitLang; -import ru.fusionsoft.dbgit.core.DBGitPath; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; -import ru.fusionsoft.dbgit.core.GitMetaDataManager; -import ru.fusionsoft.dbgit.data_table.ICellData; -import ru.fusionsoft.dbgit.data_table.RowData; -import ru.fusionsoft.dbgit.data_table.TreeMapRowData; -import ru.fusionsoft.dbgit.dbobjects.DBTable; -import ru.fusionsoft.dbgit.dbobjects.DBTableData; -import ru.fusionsoft.dbgit.utils.CalcHash; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -/** - * Meta class for Table data - * @author mikle - * - */ -public class MetaTableData extends MetaBase { - protected DBTable table = null; - private DBTableData dataTable = null; - - private TreeMapRowData mapRows = null; - - public MetaTableData() { - setDbType(); - setDbVersion(); - } - - public MetaTableData(DBTable tbl) throws ExceptionDBGit { - setDbType(); - setDbVersion(); - setTable(tbl); - } - - - public DBTable getTable() { - return table; - } - - public TreeMap getmapRows() { - return mapRows; - } - - public DBTableData getDataTable() { - return dataTable; - } - - public void setMapRows(TreeMapRowData mapRows) { - this.mapRows = mapRows; - } - - public void setDataTable(DBTableData dataTable) { - this.dataTable = dataTable; - } - - public void setTable(DBTable table) throws ExceptionDBGit { - this.table = table; - setName(table.getSchema()+"/"+table.getName()+"."+getType().getValue()); - } - - - - @Override - public void setName(String name) throws ExceptionDBGit { - if (table == null) { - NameMeta nm = MetaObjectFactory.parseMetaName(name); - table = new DBTable(); - table.setSchema(nm.getSchema()); - table.setName(nm.getName()); - } - - super.setName(name); - } - - @Override - public DBGitMetaType getType() { - return DBGitMetaType.DbGitTableData; - } - - public CSVFormat getCSVFormat() { - return CSVFormat.DEFAULT - //.withRecordSeparator("\n") - .withDelimiter(';') - .withNullString("") - .withQuote('"') - //.withQuoteMode(QuoteMode.ALL) - ; - } - - public MetaTable getMetaTable() throws ExceptionDBGit { - String metaTblName = table.getSchema()+"/"+table.getName()+"."+DBGitMetaType.DBGitTable.getValue(); - GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); - - IMapMetaObject dbObjs = gmdm.getCacheDBMetaData(); - MetaTable metaTable = (MetaTable) dbObjs.get(metaTblName); - if (metaTable == null ) { - metaTable = new MetaTable(); - metaTable.loadFromDB(table); - } - return metaTable; - } - - public MetaTable getMetaTableFromFile() throws ExceptionDBGit { - String metaTblName = table.getSchema()+"/"+table.getName()+"."+DBGitMetaType.DBGitTable.getValue(); - GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); - - MetaTable metaTable = (MetaTable)gmdm.loadMetaFile(metaTblName); - if (metaTable != null) - return metaTable; - - return getMetaTable(); - } - - - @Override - public boolean serialize(OutputStream stream) throws Exception { - Integer count = 0; - Set fields = null; - - if (mapRows == null) { - return false; - } - - CSVPrinter csvPrinter = new CSVPrinter(new OutputStreamWriter(stream), getCSVFormat()); - - for (RowData rd : mapRows.values()) { - if (count == 0) { - fields = rd.getData().keySet(); - csvPrinter.printRecord(fields); - } - - rd.saveDataToCsv(csvPrinter, getTable()); - - count++; - } - csvPrinter.close(); - return true; - } - - @Override - public IMetaObject deSerialize(InputStream stream) throws Exception { - - MetaTable metaTable = getMetaTableFromFile(); - - CSVParser csvParser = new CSVParser(new InputStreamReader(stream), getCSVFormat()); - List csvRecords = csvParser.getRecords(); - - if (csvRecords.size() > 0) { - CSVRecord titleColumns = csvRecords.get(0); - - mapRows = new TreeMapRowData(); - - for (int i = 1; i < csvRecords.size(); i++) { - RowData rd = new RowData(csvRecords.get(i), metaTable, titleColumns); - mapRows.put(rd); - } - } - - csvParser.close(); - - //saveToFile("test"); - - return this; - } - - public boolean loadPortionFromDB(int currentPortionIndex) throws ExceptionDBGit { - return loadPortionFromDB(currentPortionIndex, 0); - } - - public boolean loadPortionFromDB(int currentPortionIndex, int tryNumber) throws ExceptionDBGit { - try { - IDBAdapter adapter = AdapterFactory.createAdapter(); - MetaTable metaTable = getMetaTable(); - if (metaTable.getFields().size() == 0) - return false; - - dataTable = adapter.getTableDataPortion(table.getSchema(), table.getName(), currentPortionIndex, 0); - - ResultSet rs = dataTable.getResultSet(); - - if (dataTable.getErrorFlag() > 0) { - ConsoleWriter.printlnColor(DBGitLang.getInstance().getValue("errors", "meta", "tooManyRecords"). - withParams(getName(), String.valueOf(IDBAdapter.MAX_ROW_COUNT_FETCH)), FColor.RED, 0); - return false; - } - - mapRows = new TreeMapRowData(); - - while(rs.next()){ - RowData rd = new RowData(rs, metaTable); - mapRows.put(rd); - } - return true; - } catch (Exception e) { - e.printStackTrace(); - ConsoleWriter.println(e.getMessage()); - ConsoleWriter.println(e.getLocalizedMessage()); - - try { - if (tryNumber <= DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000))) { - try { - TimeUnit.SECONDS.sleep(DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000))); - } catch (InterruptedException e1) { - throw new ExceptionDBGitRunTime(e1.getMessage()); - } - ConsoleWriter.println("Error while getting portion of data, try " + tryNumber); - return loadPortionFromDB(currentPortionIndex, tryNumber++); - } - } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - if (e instanceof ExceptionDBGit) - throw (ExceptionDBGit)e; - throw new ExceptionDBGit(e); - } - } - - @Override - public boolean loadFromDB() throws ExceptionDBGit { - try { - IDBAdapter adapter = AdapterFactory.createAdapter(); - - MetaTable metaTable = getMetaTable(); - - if (metaTable.getFields().size() == 0) - return false; - - List idColumns = metaTable.getIdColumns(); - - dataTable = adapter.getTableData(table.getSchema(), table.getName()); - - if (dataTable.getErrorFlag() > 0) { - ConsoleWriter.printlnColor(DBGitLang.getInstance().getValue("errors", "meta", "tooManyRecords"). - withParams(getName(), String.valueOf(IDBAdapter.MAX_ROW_COUNT_FETCH)), FColor.RED, 0); - return false; - } - - ResultSet rs = dataTable.getResultSet(); - - mapRows = new TreeMapRowData(); - - //System.out.println("load from db file "+getName()); - while(rs.next()){ - RowData rd = new RowData(rs, metaTable); - mapRows.put(rd); - } - return true; - /* - System.out.println("******************************************"); - System.out.println(); - */ - } catch (Exception e) { - e.printStackTrace(); - if (e instanceof ExceptionDBGit) - throw (ExceptionDBGit)e; - throw new ExceptionDBGit(e); - } - - } - - public void diff(MetaTableData ob) throws Exception { - if (mapRows.size() != ob.mapRows.size()) { - System.out.println(DBGitLang.getInstance().getValue("general", "meta", "diffSize1").withParams(String.valueOf(mapRows.size()), String.valueOf(ob.mapRows.size()))); - } - for (String rowHash : mapRows.keySet()) { - RowData r1 = mapRows.get(rowHash); - RowData r2 = ob.mapRows.get(rowHash); - - System.out.println(rowHash); - System.out.println(r1.getData()+ " "+ r2.getData()); - - if (r1.getData().size() != r2.getData().size()) { - System.out.println(DBGitLang.getInstance().getValue("general", "meta", "diffSize2").withParams(rowHash)); - } - - for (String col : r1.getData().keySet()) { - String d1 = r1.getData().get(col).convertToString(); - String d2 = r2.getData().get(col).convertToString(); - - if (d1 != d2) { - if (!d1.equals(r2.getData().get(col))) { - System.out.println(DBGitLang.getInstance().getValue("general", "meta", "diffDataRow"). - withParams(rowHash, col, r1.getData().get(col).toString(), r2.getData().get(col).toString())); - } - } - } - } - } - - - @Override - public String getHash() { - CalcHash ch = new CalcHash(); - if (mapRows == null) - return EMPTY_HASH; - - if (mapRows.size() == 0) - return EMPTY_HASH; - - //System.out.println(getName()); - int n = 0; - for (RowData rd : mapRows.values()) { - ch.addData(rd.getHashRow()); - //System.out.println("row "+n+" "+rd.getHashRow()); - n++; - } - - return ch.calcHashStr(); - } - - @Override - public int addToGit() throws ExceptionDBGit { - int count = super.addToGit(); - - if (mapRows == null) return count; - - for (RowData rd : mapRows.values()) { - for (ICellData cd : rd.getData().values()) { - count += cd.addToGit(); - } - } - - return count; - } - - @Override - public int removeFromGit() throws ExceptionDBGit { - int count = super.removeFromGit(); - - if (mapRows == null) - return 1; - - for (RowData rd : mapRows.values()) { - for (ICellData cd : rd.getData().values()) { - count += cd.removeFromGit(); - } - } - - return count; - } - -} +package ru.fusionsoft.dbgit.meta; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.TimeUnit; + +import de.siegmar.fastcsv.reader.CsvParser; +import de.siegmar.fastcsv.reader.CsvReader; +import de.siegmar.fastcsv.reader.CsvRow; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.csv.CSVRecord; + +import com.diogonunes.jcdp.color.api.Ansi.FColor; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import ru.fusionsoft.dbgit.adapters.AdapterFactory; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.DBGitConfig; +import ru.fusionsoft.dbgit.core.DBGitLang; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; +import ru.fusionsoft.dbgit.core.GitMetaDataManager; +import ru.fusionsoft.dbgit.data_table.ICellData; +import ru.fusionsoft.dbgit.data_table.MapFileData; +import ru.fusionsoft.dbgit.data_table.RowData; +import ru.fusionsoft.dbgit.data_table.TreeMapRowData; +import ru.fusionsoft.dbgit.dbobjects.DBTable; +import ru.fusionsoft.dbgit.dbobjects.DBTableData; +import ru.fusionsoft.dbgit.utils.CalcHash; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; +import ru.fusionsoft.dbgit.utils.LoggerUtil; + +/** + * Meta class for Table data + * @author mikle + * + */ +public class MetaTableData extends MetaBase { + private Logger logger = LoggerUtil.getLogger(this.getClass()); + protected DBTable table = null; + private DBTableData dataTable = null; + + private TreeMapRowData mapRows = null; + private List fields = new ArrayList<>(); + + public MetaTableData() { + setDbType(); + setDbVersion(); + } + + public MetaTableData(DBTable tbl) throws ExceptionDBGit { + setDbType(); + setDbVersion(); + setTable(tbl); + } + + + public DBTable getTable() { + return table; + } + + public TreeMap getmapRows() { + return mapRows; + } + + public DBTableData getDataTable() { + return dataTable; + } + + public void setMapRows(TreeMapRowData mapRows) { + this.mapRows = mapRows; + } + + public void setDataTable(DBTableData dataTable) { + this.dataTable = dataTable; + } + + 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 { + if (table == null) { + NameMeta nm = MetaObjectFactory.parseMetaName(name); + table = new DBTable.OnlyNameDBTable(nm.getName(), nm.getSchema()); + } + + super.setName(name); + } + + @Override + public DBGitMetaType getType() { + return DBGitMetaType.DbGitTableData; + } + + public CSVFormat getCSVFormat() { + return CSVFormat.DEFAULT + //.withRecordSeparator("\n") + .withDelimiter(';') + .withNullString("") + .withQuote('"') + //.withQuoteMode(QuoteMode.ALL) + ; + } + + public MetaTable getMetaTable() throws ExceptionDBGit { + String metaTblName = table.getSchema()+"/"+table.getName()+"."+DBGitMetaType.DBGitTable.getValue(); + GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); + + IMapMetaObject dbObjs = gmdm.getCacheDBMetaData(); + MetaTable metaTable = (MetaTable) dbObjs.get(metaTblName); + if (metaTable == null ) { + metaTable = new MetaTable(); + metaTable.loadFromDB(table); + } + return metaTable; + } + + public MetaTable getMetaTableFromFile() throws ExceptionDBGit { + String metaTblName = table.getSchema()+"/"+table.getName()+"."+DBGitMetaType.DBGitTable.getValue(); + GitMetaDataManager gmdm = GitMetaDataManager.getInstance(); + + MetaTable metaTable = (MetaTable)gmdm.loadMetaFile(metaTblName); + if (metaTable != null) + return metaTable; + + //TODO ... which is not from file, but from db + return getMetaTable(); + } + + + @Override + public boolean serialize(OutputStream stream) throws Exception { + Integer count = 0; + Set fields = null; + + if (mapRows == null) { + return false; + } + + CSVPrinter csvPrinter = new CSVPrinter(new OutputStreamWriter(stream), getCSVFormat()); + + for (RowData rd : mapRows.values()) { + if (count == 0) { + fields = rd.getData(this.fields).keySet(); + csvPrinter.printRecord(fields); + } + + rd.saveDataToCsv(csvPrinter, getTable()); + + count++; + } + csvPrinter.close(); + return true; + } + + @Override + public IMetaObject deSerialize(File file) throws Exception { + MetaTable metaTable = getMetaTableFromFile(); + + CsvReader csvReader = new CsvReader(); + csvReader.setFieldSeparator(';'); + csvReader.setContainsHeader(false); + int i = 1; + + try (CsvParser csvParser = csvReader.parse(file, StandardCharsets.UTF_8)) { + CsvRow row; + boolean flag = false; + mapRows = new TreeMapRowData(); + CsvRow titleColumns = null; + + + while ((row = csvParser.nextRow()) != null) { + if (!flag) { + titleColumns = row; + fields = row.getFields(); +// System.err.println("fields = " + fields); + } else { + RowData rd = new RowData(row, metaTable, titleColumns); + mapRows.put(rd); + i++; + } + flag = true; + } + } catch (Throwable ex){ + ConsoleWriter.detailsPrint(DBGitLang.getInstance().getValue("general", "meta", "loadRow").withParams(String.valueOf(i) )); + warnFilesNotFound(); + throw ex; + } + ConsoleWriter.detailsPrint(DBGitLang.getInstance().getValue("general", "meta", "loadedRow").withParams(String.valueOf(i) )); + warnFilesNotFound(); + + return this; + } + + + @Override + @Deprecated + public IMetaObject deSerialize(InputStream stream) throws Exception { + + MetaTable metaTable = getMetaTableFromFile(); + + CSVParser csvParser = new CSVParser(new InputStreamReader(stream), getCSVFormat()); + List csvRecords = csvParser.getRecords(); + + if (csvRecords.size() > 0) { + CSVRecord titleColumns = csvRecords.get(0); + fields.clear(); + for (int i = 0; i < csvRecords.get(0).size(); i++) { + fields.add(csvRecords.get(0).get(i)); + } + + mapRows = new TreeMapRowData(); + + for (int i = 1; i < csvRecords.size(); i++) { + RowData rd = new RowData(csvRecords.get(i), metaTable, titleColumns); + mapRows.put(rd); + } + } + + + csvParser.close(); + + //saveToFile("test"); + + return this; + } + + public boolean loadPortionFromDB(int currentPortionIndex) throws ExceptionDBGit { + return loadPortionFromDB(currentPortionIndex, 0); + } + + public boolean loadPortionFromDB(int currentPortionIndex, int tryNumber) throws ExceptionDBGit { + try { + IDBAdapter adapter = AdapterFactory.createAdapter(); + MetaTable metaTable = getMetaTable(); + if (metaTable.getFields().size() == 0) + return false; + + dataTable = adapter.getTableDataPortion(table.getSchema(), table.getName(), currentPortionIndex, 0); + + ResultSet rs = dataTable.resultSet(); + + if (dataTable.errorFlag() > 0) { + final String tooManyRecordsMsg = DBGitLang.getInstance().getValue("errors", "meta", "tooManyRecords").withParams(getName(), String.valueOf(IDBAdapter.MAX_ROW_COUNT_FETCH)); + ConsoleWriter.printlnColor(tooManyRecordsMsg, FColor.RED, 0); + return false; + } + + mapRows = new TreeMapRowData(); + + boolean flag = false; + while(rs.next()){ + + if (!flag) { + fields.clear(); + for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) { + String columnName = rs.getMetaData().getColumnName(i + 1); + if (columnName.equalsIgnoreCase("DBGIT_ROW_NUM")) + continue; + fields.add(columnName); + } + } + + flag = true; + RowData rd = new RowData(rs, metaTable); + mapRows.put(rd); + } + + + + return true; + } catch (Exception e) { + + ConsoleWriter.println(e.getLocalizedMessage(), messageLevel); + ConsoleWriter.detailsPrintln(ExceptionUtils.getStackTrace(e), messageLevel); + logger.error(DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(), e); + + try { + if (tryNumber <= DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000))) { + try { + TimeUnit.SECONDS.sleep(DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000))); + } catch (InterruptedException e1) { + throw new ExceptionDBGitRunTime(e1.getMessage()); + } + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("errors", "dataTable", "tryAgain") + .withParams(String.valueOf(tryNumber)) + , messageLevel + ); + return loadPortionFromDB(currentPortionIndex, tryNumber++); + } + } catch (Exception e1) { + throw new ExceptionDBGitRunTime(e1); + // TODO Auto-generated catch block +// e1.printStackTrace(); + } + + if (e instanceof ExceptionDBGit) throw (ExceptionDBGit)e; + throw new ExceptionDBGit(e); + } + } + + @Override + public boolean loadFromDB() throws ExceptionDBGit { + try { + IDBAdapter adapter = AdapterFactory.createAdapter(); + + MetaTable metaTable = getMetaTable(); + + if (metaTable.getFields().size() == 0) + return false; + + dataTable = adapter.getTableData(table.getSchema(), table.getName()); + + if (dataTable.errorFlag() > 0) { + ConsoleWriter.printlnColor(DBGitLang.getInstance().getValue("errors", "meta", "tooManyRecords"). + withParams(getName(), String.valueOf(IDBAdapter.MAX_ROW_COUNT_FETCH)), FColor.RED, 0); + return false; + } + + ResultSet rs = dataTable.resultSet(); + + mapRows = new TreeMapRowData(); + + //System.out.println("load from db file "+getName()); + while(rs.next()){ + RowData rd = new RowData(rs, metaTable); + mapRows.put(rd); + } + return true; + /* + System.out.println("******************************************"); + System.out.println(); + */ + } catch (Exception e) { + throw new ExceptionDBGit("Error loading table data from DB", e); + } + + } + + public void diff(MetaTableData ob) throws Exception { + if (mapRows.size() != ob.mapRows.size()) { + System.out.println(DBGitLang.getInstance().getValue("general", "meta", "diffSize1").withParams(String.valueOf(mapRows.size()), String.valueOf(ob.mapRows.size()))); + } + for (String rowHash : mapRows.keySet()) { + RowData r1 = mapRows.get(rowHash); + RowData r2 = ob.mapRows.get(rowHash); + + System.out.println(rowHash); + System.out.println(r1.getData(fields)+ " "+ r2.getData(ob.fields)); + + if (r1.getData(fields).size() != r2.getData(ob.fields).size()) { + System.out.println(DBGitLang.getInstance().getValue("general", "meta", "diffSize2").withParams(rowHash)); + } + + for (String col : r1.getData(fields).keySet()) { + String d1 = r1.getData(fields).get(col).convertToString(); + String d2 = r2.getData(ob.fields).get(col).convertToString(); + + if (d1 != d2) { + if (!d1.equals(r2.getData(ob.fields).get(col))) { + System.out.println(DBGitLang.getInstance().getValue("general", "meta", "diffDataRow"). + withParams(rowHash, col, r1.getData(fields).get(col).toString(), r2.getData(ob.fields).get(col).toString())); + } + } + } + } + } + + + @Override + public String getHash() { + CalcHash ch = new CalcHash(); + if (mapRows == null) + return EMPTY_HASH; + + if (mapRows.size() == 0) + return EMPTY_HASH; + + //System.out.println(getName()); + int n = 0; + for (RowData rd : mapRows.values()) { + ch.addData(rd.getHashRow()); + //System.out.println("row "+n+" "+rd.getHashRow()); + n++; + } + + return ch.calcHashStr(); + } + + @Override + public int addToGit() throws ExceptionDBGit { + int count = super.addToGit(); + + if (mapRows == null) return count; + + for (RowData rd : mapRows.values()) { + for (ICellData cd : rd.getData(fields).values()) { + count += cd.addToGit(); + } + } + + return count; + } + + @Override + public int removeFromGit() throws ExceptionDBGit { + int count = super.removeFromGit(); + + if (mapRows == null) + return 1; + + for (RowData rd : mapRows.values()) { + for (ICellData cd : rd.getData(fields).values()) { + count += cd.removeFromGit(); + } + } + + return count; + } + + public List getFields() { + return fields; + } + + private void warnFilesNotFound(){ + Set filesNotFound = MapFileData.getFilesNotFound(); + if(filesNotFound != null && filesNotFound.size() > 0){ + ConsoleWriter.detailsPrintlnColor(DBGitLang.getInstance().getValue("errors", "dataTable", "filesNotFound") + .withParams(String.join(";", filesNotFound)) + , FColor.YELLOW, messageLevel + ); + filesNotFound.clear(); + } + + } +} 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/meta/SortedListMetaObject.java b/src/main/java/ru/fusionsoft/dbgit/meta/SortedListMetaObject.java index de3c517..16fd538 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/SortedListMetaObject.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/SortedListMetaObject.java @@ -8,7 +8,7 @@ import ru.fusionsoft.dbgit.dbobjects.DBTable; import ru.fusionsoft.dbgit.utils.ConsoleWriter; -import java.sql.Timestamp; + import java.util.*; import java.util.stream.Collectors; @@ -28,23 +28,42 @@ public SortedListMetaObject(Collection fromCollection){ calculateImoCrossDependencies(); } + public Collection getCollection(){ + return collection; +} + public List sortFromDependencies() throws ExceptionDBGit { + if (listFromDependant == null) { + listFromDependant = createSortedList(false); + } + return listFromDependant; + + } + public List sortFromReferenced() throws ExceptionDBGit { + if (listFromFree == null) { + listFromFree = createSortedList(true); + } + return listFromFree; + } + private void calculateImoCrossDependencies(){ - Timestamp timestampBefore = new Timestamp(System.currentTimeMillis()); for(DBGitMetaType metaType : Sets.newHashSet(DBGitMetaType.DBGitTable, DBGitMetaType.DbGitFunction)){ - List objectsOfType = collection.stream().filter(x->x.getType().equals(metaType) ).collect(Collectors.toList()); + List objectsOfType = collection.stream() + .filter( x->x.getType().equals(metaType) ) + .collect(Collectors.toList()); + + Map realNamesToMetaNames = objectsOfType.stream().collect(Collectors.toMap( - x->x.getUnderlyingDbObject().getSchema() + "." + x.getUnderlyingDbObject().getName(), - IMetaObject::getName - ) - ); + x-> x.getUnderlyingDbObject().getSchema() + "." + x.getUnderlyingDbObject().getName(), + IMetaObject::getName + )); for(IMetaObject imo : objectsOfType){ if(imo.getType().equals(DBGitMetaType.DbGitFunction)){ DBSQLObject dbsql = (DBSQLObject) imo.getUnderlyingDbObject(); Set deps = realNamesToMetaNames.keySet().stream() - .filter( x -> dbsql.getSql().contains(x) && !(dbsql.getSchema()+"."+dbsql.getName()).equals(x) ) + .filter( x -> dbsql.getSql().contains(x) /*&& !(dbsql.getSchema()+"."+dbsql.getName()).equals(x)*/ ) .map(realNamesToMetaNames::get) .collect(Collectors.toSet()); dbsql.setDependencies(deps); @@ -52,111 +71,77 @@ private void calculateImoCrossDependencies(){ if(imo.getType().equals(DBGitMetaType.DBGitTable)){ DBTable dbTable = (DBTable) imo.getUnderlyingDbObject(); Set deps = realNamesToMetaNames.values().stream() - .filter( x -> dbTable.getDependencies().contains(x) && !x.equals(imo.getName()) ) - .collect(Collectors.toSet()); - dbTable.setDependencies(deps); + .filter( x -> dbTable.getDependencies().contains(x) /*&& !x.equals(imo.getName())*/ ) + .collect(Collectors.toSet()); + dbTable.getDependencies().addAll(deps); } } } - Timestamp timestampAfter = new Timestamp(System.currentTimeMillis()); - Long diff = timestampAfter.getTime() - timestampBefore.getTime(); - ConsoleWriter.detailsPrintlnGreen(DBGitLang.getInstance().getValue("general", "time").withParams(diff.toString())); - }; - - public List sortFromDependant() throws ExceptionDBGit { - if (listFromDependant == null) { - listFromDependant = new ArrayList<>(); - List types = Arrays - .stream(DBGitMetaType.values()) - .sorted(Comparator.comparing(DBGitMetaType::getPriority).reversed()) - .collect(Collectors.toList()); - - for (DBGitMetaType tp : types) { - - List objectsOfType = collection.stream().filter(x -> x.getType().equals(tp)).collect(Collectors.toList()); - if (!objectsOfType.isEmpty()) { - if (tp.equals(DBGitMetaType.DBGitTable) || (objectsOfType.get(0) instanceof MetaSql)) { + } - Set namesAllOfType = objectsOfType.stream().map(IMetaObject::getName).collect(Collectors.toSet()); - List objectsL0 = objectsOfType.stream() - .filter(x -> x.getUnderlyingDbObject().getDependencies().size() == 0) + public List createSortedList(boolean isSortedFromFree) throws ExceptionDBGit { + List list = new ArrayList<>(); + Comparator typeComparator = isSortedFromFree + ? Comparator.comparing(DBGitMetaType::getPriority) + : Comparator.comparing(DBGitMetaType::getPriority).reversed(); + Comparator imoComparator = isSortedFromFree + ? imoDependenceComparator + : imoDependenceComparator.reversed(); + + List types = Arrays + .stream(DBGitMetaType.values()) + .sorted(typeComparator) + .collect(Collectors.toList()); + + for (DBGitMetaType tp : types) { + List objectsOfType = collection.stream().filter(x -> x.getType().equals(tp)).collect(Collectors.toList()); + if (!objectsOfType.isEmpty()) { + if (tp.equals(DBGitMetaType.DBGitTable) || objectsOfType.get(0) instanceof MetaSql) { + Set namesAllOfType = objectsOfType.stream().map(IMetaObject::getName).collect(Collectors.toSet()); + List objectsL0 = objectsOfType.stream() + .filter(x -> { + Set deps = x.getUnderlyingDbObject().getDependencies(); + return deps.size() == 0 || ( deps.size() == 1 && deps.contains(x.getName()) ); + }) + .collect(Collectors.toList()); + + objectsOfType.removeAll(objectsL0); + while (!objectsOfType.isEmpty()) { + Set namesL0 = objectsL0.stream().map(IMetaObject::getName).collect(Collectors.toSet()); + List objectsL1 = objectsOfType + .stream() + .filter(x -> { + Set actualDeps = new HashSet<>(x.getUnderlyingDbObject().getDependencies()); + actualDeps.retainAll(namesAllOfType); //only deps of same type + actualDeps.remove(x.getName()); + return namesL0.containsAll(actualDeps); + }) + .sorted(imoComparator) .collect(Collectors.toList()); - - objectsOfType.removeAll(objectsL0); - while (!objectsOfType.isEmpty()) { - Set namesL0 = objectsL0.stream().map(IMetaObject::getName).collect(Collectors.toSet()); - List objectsL1 = objectsOfType - .stream() - .filter(x -> { - Set actualDeps = new HashSet<>(x.getUnderlyingDbObject().getDependencies()); - actualDeps.retainAll(namesAllOfType); - return namesL0.containsAll(actualDeps); - }) - .sorted(imoDependenceComparator.reversed()) - .collect(Collectors.toList()); - if (objectsL1.isEmpty()) { - warnNotAdded(objectsOfType); - throw new ExceptionDBGit("infinite loop"); - } - objectsOfType.removeAll(objectsL1); - objectsL0.addAll(0, objectsL1); + if (objectsL1.isEmpty()) { + warnNotAdded(objectsOfType); + throw new ExceptionDBGit("infinite loop"); } - listFromDependant.addAll(objectsL0); - } else { - listFromDependant.addAll(objectsOfType); + objectsOfType.removeAll(objectsL1); + if(isSortedFromFree) { objectsL0.addAll(objectsL1); } + else { objectsL0.addAll(0, objectsL1); } } + list.addAll(objectsL0); + } else { + list.addAll(objectsOfType); } } } - return listFromDependant; - - }; - public List sortFromFree() throws ExceptionDBGit { - if (listFromFree == null) { - listFromFree = new ArrayList<>(); - List types = Arrays.stream(DBGitMetaType.values()) - .sorted(Comparator.comparing(DBGitMetaType::getPriority)) - .collect(Collectors.toList()); - - for (DBGitMetaType tp : types) { - List objectsOfType = collection.stream().filter(x -> x.getType().equals(tp)).collect(Collectors.toList()); - if (!objectsOfType.isEmpty()) { - if (tp.equals(DBGitMetaType.DBGitTable) || objectsOfType.get(0) instanceof MetaSql) { - Set namesAllOfType = objectsOfType.stream().map(IMetaObject::getName).collect(Collectors.toSet()); - List objectsL0 = objectsOfType.stream().filter(x -> x.getUnderlyingDbObject().getDependencies().size() == 0).collect(Collectors.toList()); - - objectsOfType.removeAll(objectsL0); - while (!objectsOfType.isEmpty()) { - Set namesL0 = objectsL0.stream().map(IMetaObject::getName).collect(Collectors.toSet()); - List objectsL1 = objectsOfType - .stream() - .filter(x -> { - Set actualDeps = new HashSet<>(x.getUnderlyingDbObject().getDependencies()); - actualDeps.retainAll(namesAllOfType); - return namesL0.containsAll(actualDeps); - }) - .sorted(imoDependenceComparator) - .collect(Collectors.toList()); - if (objectsL1.isEmpty()) { - warnNotAdded(objectsOfType); - throw new ExceptionDBGit("infinite loop"); - } - objectsOfType.removeAll(objectsL1); - objectsL0.addAll(objectsL1); - } - listFromFree.addAll(objectsL0); - } else { - listFromFree.addAll(objectsOfType); - } - } +// int i = 0; +// for(IMetaObject imo : list){ +// ConsoleWriter.printlnRed(MessageFormat.format("{0}. {1}", i++, imo.getName())); +// } + return list; + } - } - } - return listFromFree; - }; public static Comparator imoTypeComparator = Comparator.comparing(x->x.getType().getPriority()); public static Comparator imoDependenceComparator = (o1, o2) -> { @@ -178,8 +163,11 @@ public List sortFromFree() throws ExceptionDBGit { }; public void warnNotAdded(List remained){ - ConsoleWriter.detailsPrintlnRed("There were objects with unsatisfied dependencies, " + - "they will NOT be included in restore list!\n"); + ConsoleWriter.printlnRed(DBGitLang.getInstance() + .getValue("errors", "unsatisfiedDependencies") + , 1 + ); + remained.forEach( x -> ConsoleWriter.printlnColor(x.getName(), Ansi.FColor.MAGENTA, 1) ); } diff --git a/src/main/java/ru/fusionsoft/dbgit/meta/TreeMapMetaObject.java b/src/main/java/ru/fusionsoft/dbgit/meta/TreeMapMetaObject.java index f417e35..d167b3d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/meta/TreeMapMetaObject.java +++ b/src/main/java/ru/fusionsoft/dbgit/meta/TreeMapMetaObject.java @@ -36,7 +36,7 @@ public int compare(String nm1, String nm2) { } - public TreeMapMetaObject(List from){ + public TreeMapMetaObject(Collection from){ this(); this.putAll(from.stream().collect(Collectors.toMap(IMetaObject::getName, key->key))); } diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssql.java index 2d0c983..f33d99d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssql.java @@ -1,21 +1,23 @@ package ru.fusionsoft.dbgit.mssql; +import com.google.common.collect.ImmutableMap; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import ru.fusionsoft.dbgit.adapters.DBAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBAdapterRestoteMetaData; import ru.fusionsoft.dbgit.adapters.IFactoryDBBackupAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; -import ru.fusionsoft.dbgit.core.DBGitConfig; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; +import ru.fusionsoft.dbgit.core.*; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.core.db.FieldType; import ru.fusionsoft.dbgit.data_table.*; import ru.fusionsoft.dbgit.dbobjects.*; import ru.fusionsoft.dbgit.meta.IMapMetaObject; +import ru.fusionsoft.dbgit.meta.TreeMapMetaObject; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.LoggerUtil; +import ru.fusionsoft.dbgit.utils.StringProperties; import java.sql.*; import java.util.*; @@ -26,18 +28,18 @@ public class DBAdapterMssql extends DBAdapter { public static final String DEFAULT_MAPPING_TYPE = "varchar"; private static final HashSet systemSchemas = new HashSet<>(Arrays.asList( - "db_denydatawriter", - "db_datawriter", - "db_accessadmin", - "db_ddladmin", - "db_securityadmin", - "db_denydatareader", - "db_backupoperator", - "db_datareader", - "db_owner", - "sys", - "INFORMATION_SCHEMA" - )); + "db_denydatawriter", + "db_datawriter", + "db_accessadmin", + "db_ddladmin", + "db_securityadmin", + "db_denydatareader", + "db_backupoperator", + "db_datareader", + "db_owner", + "sys", + "INFORMATION_SCHEMA" + )); //Stubs for MSSQL adapter, marked as "TODO Auto-generated method stub" //And some unfinished implementations marked as "TODO MSSQL *" @@ -64,33 +66,30 @@ public void endUpdateDB() { @Override public IMapMetaObject loadCustomMetaObjects() { - // TODO Auto-generated method stub - return null; + return new TreeMapMetaObject(Collections.emptyList()); } @Override public Map getSchemes() { - Map listScheme = new HashMap(); - try { - Connection connect = getConnection(); - DatabaseMetaData meta = connect.getMetaData(); - ResultSet rs = meta.getSchemas(); + final Map listScheme = new HashMap<>(); + try (ResultSet rs = getConnection().getMetaData().getSchemas()){ + // made without query // Statement stmt = connect.createStatement(); // ResultSet rs = stmt.executeQuery(query); while(rs.next()){ + final String name = rs.getString("TABLE_SCHEM"); + // May also get catalog names that belong to scheme as "TABLE_CATALOG" - String name = rs.getString("TABLE_SCHEM"); if(!systemSchemas.contains(name)) { - DBSchema scheme = new DBSchema(name); - rowToProperties(rs, scheme.getOptions()); + final DBSchema scheme = new DBSchema(name, new StringProperties(rs)); listScheme.put(name, scheme); } } - //stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "schemes").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "schemes").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "schemes").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listScheme; @@ -98,8 +97,8 @@ public Map getSchemes() { @Override public Map getTableSpaces() { - - String query = "SELECT \n" + + final Map listTableSpace = new HashMap<>(); + final String query = "SELECT \n" + "[SFG].name AS [File Group Name],\n" + "[SFG].*,\n" + "[SDB].name AS [Database Name],\n" + @@ -158,501 +157,524 @@ public Map getTableSpaces() { " [filegroup_guid],\n" + " [log_filegroup_id]\n" + "DROP TABLE #fgroups\n"; - Map listTableSpace = new HashMap(); - try { - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ - String name = rs.getString("File Group Name"); - DBTableSpace dbTableSpace = new DBTableSpace(name); - rowToProperties(rs, dbTableSpace.getOptions()); + final String name = rs.getString("File Group Name"); + final DBTableSpace dbTableSpace = new DBTableSpace(name, new StringProperties(rs)); listTableSpace.put(name, dbTableSpace); } - stmt.close(); - }catch(Exception e) { - logger.error(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); - } - return listTableSpace; - } - private DBSequence sequenceFromResultSet(ResultSet rs, String schema){ - try { - String nameSeq = rs.getString("name"); - Long valueSeq = rs.getLong("current_value"); - DBSequence sequence = new DBSequence(); - sequence.setName(nameSeq); - sequence.setSchema(schema); - sequence.setValue(valueSeq); - rowToProperties(rs, sequence.getOptions()); - return sequence; - } catch (Exception ex){ - logger.error(ex.getMessage(), ex); - throw new ExceptionDBGitRunTime(ex.getMessage(), ex); + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tablespace").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + + return listTableSpace; } @Override public Map getSequences(String schema) { - Map listSequence = new HashMap(); - try { - Connection connect = getConnection(); - String query = - "SELECT seq.*,\n" + - "TYPE_NAME(seq.system_type_id) as typeName,\n" + - "SCHEMA_NAME(seq.schema_id) as owner \n" + - "FROM sys.objects, sys.SEQUENCES seq \n" + - "WHERE sys.objects.object_id = seq.object_id \n" + - "AND SCHEMA_NAME(seq.schema_id) = '"+schema+"'"; + final Map listSequence = new HashMap(); + final String query = + "SELECT seq.*,\n" + + "TYPE_NAME(seq.system_type_id) as typeName,\n" + + "SCHEMA_NAME(seq.schema_id) as owner \n" + + "FROM sys.objects, sys.SEQUENCES seq \n" + + "WHERE sys.objects.object_id = seq.object_id \n" + + "AND SCHEMA_NAME(seq.schema_id) = '"+schema+"'"; + + try(Statement stmtValue = getConnection().createStatement(); ResultSet rs = stmtValue.executeQuery(query)){ - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); while(rs.next()){ - String nameSeq = rs.getString("name"); - listSequence.put(nameSeq, sequenceFromResultSet(rs, schema)); + final String ownerSeq = "dbo"; + final String nameSeq = rs.getString("name"); + final Long valueSeq = rs.getLong("current_value"); + final DBSequence seq = new DBSequence(nameSeq, new StringProperties(rs), schema, ownerSeq, Collections.emptySet(), valueSeq); + listSequence.put(nameSeq, seq); } - stmt.close(); - }catch(Exception e) { - logger.error(e.getMessage(), e); - throw new ExceptionDBGitRunTime(e.getMessage(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "seq").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listSequence; } @Override public DBSequence getSequence(String schema, String name) { - try { - Connection connect = getConnection(); - String query = - "SELECT seq.*,\n" + - "USER_NAME(objectproperty(seq.object_id,'OwnerId')) as owner,\n" + - "TYPE_NAME(seq.system_type_id) as typeName, " + - "SCHEMA_NAME(seq.schema_id) as schemaName " + - "FROM sys.objects, sys.SEQUENCES seq " + - "WHERE sys.objects.object_id = seq.object_id " + - "AND SCHEMA_NAME(seq.schema_id) = '"+schema+"' " + - "AND seq.name = '" + name + "'\n"; - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final String query = + "SELECT seq.*,\n" + + "USER_NAME(objectproperty(seq.object_id,'OwnerId')) as owner,\n" + + "TYPE_NAME(seq.system_type_id) as typeName, " + + "SCHEMA_NAME(seq.schema_id) as schemaName " + + "FROM sys.objects, sys.SEQUENCES seq " + + "WHERE sys.objects.object_id = seq.object_id " + + "AND SCHEMA_NAME(seq.schema_id) = '"+schema+"' " + + "AND seq.name = '" + name + "'\n"; + + try(Statement stmtValue = getConnection().createStatement(); ResultSet rs = stmtValue.executeQuery(query)){ + + if(rs.next()){ + final String ownerSeq = "dbo"; + final String nameSeq = rs.getString("name"); + final Long valueSeq = rs.getLong("current_value"); + return new DBSequence(nameSeq, new StringProperties(rs), schema, ownerSeq, Collections.emptySet(), valueSeq); + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } - DBSequence sequence = null; - while (rs.next()) { - sequence = sequenceFromResultSet(rs, schema); - } - stmt.close(); - return sequence; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "sequences").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "sequences").toString(), e); + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "seq").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public Map getTables(String schema) { - Map listTable = new HashMap(); - try { - String query = - "SELECT TABLE_NAME as 'name', TABLE_CATALOG as 'database', TABLE_SCHEMA as 'schema'\n" + - "FROM INFORMATION_SCHEMA.TABLES \n" + - "WHERE INFORMATION_SCHEMA.TABLES.TABLE_SCHEMA = '" + schema + "'\n" + - "AND INFORMATION_SCHEMA.TABLES.TABLE_TYPE = 'BASE TABLE'"; - Connection connect = getConnection(); - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - + final Map listTable = new HashMap<>(); + final String query = + "SELECT TABLE_NAME as 'name', TABLE_CATALOG as 'database', TABLE_SCHEMA as 'schema'\n" + + "FROM INFORMATION_SCHEMA.TABLES \n" + + "WHERE INFORMATION_SCHEMA.TABLES.TABLE_SCHEMA = '" + schema + "'\n" + + "AND INFORMATION_SCHEMA.TABLES.TABLE_TYPE = 'BASE TABLE'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { while(rs.next()){ - String nameTable = rs.getString("name"); - DBTable table = new DBTable(nameTable); - table.setSchema(schema); - rowToProperties(rs, table.getOptions()); + //TODO retrieve table comment + //TODO retrieve table owner + final String nameTable = rs.getString("name"); + final String ownerTable = ""; + final String commentTable = ""; + final StringProperties options = new StringProperties(rs); + final Set dependencies = rs.getArray("dependencies") != null + ? new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())) + : Collections.emptySet(); + + final DBTable table = new DBTable(nameTable, options, schema, ownerTable, dependencies, commentTable); listTable.put(nameTable, table); } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listTable; } @Override public DBTable getTable(String schema, String name) { - DBTable table = null; - try(Statement stmt = getConnection().createStatement()) { - String query = - "SELECT\n" + - " o.name tableName, t.TABLE_SCHEMA schemaName, t.TABLE_CATALOG catalogName,\n" + - " CASE WHEN o.principal_id is NOT NULL THEN (SELECT name FROM sys.database_principals dp WHERE dp.principal_id=o.principal_id)\n" + - " ELSE (SELECT dp.name FROM sys.database_principals dp,sys.schemas s WHERE s.schema_id=o.schema_id and s.principal_id=dp.principal_id)\n" + - " END as owner\n" + - "FROM sys.objects o, INFORMATION_SCHEMA.TABLES t\n" + - "WHERE o.type='U' AND o.name = t.TABLE_NAME AND t.TABLE_NAME = '"+name+"' AND t.TABLE_SCHEMA = '"+schema+"'"; - - ResultSet rs = stmt.executeQuery(query); + final String query = + "SELECT\n" + + " o.name tableName, t.TABLE_SCHEMA schemaName, t.TABLE_CATALOG catalogName,\n" + + " CASE WHEN o.principal_id is NOT NULL THEN (SELECT name FROM sys.database_principals dp WHERE dp.principal_id=o.principal_id)\n" + + " ELSE (SELECT dp.name FROM sys.database_principals dp,sys.schemas s WHERE s.schema_id=o.schema_id and s.principal_id=dp.principal_id)\n" + + " END as owner\n" + + "FROM sys.objects o, INFORMATION_SCHEMA.TABLES t\n" + + "WHERE o.type='U' AND o.name = t.TABLE_NAME AND t.TABLE_NAME = '"+name+"' AND t.TABLE_SCHEMA = '"+schema+"'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + if (rs.next()){ + //TODO retrieve table comment + //TODO retrieve table owner + final String nameTable = rs.getString("name"); + final String ownerTable = ""; + final String commentTable = ""; + final StringProperties options = new StringProperties(rs); + final Set dependencies = rs.getArray("dependencies") != null + ? new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())) + : Collections.emptySet(); + + return new DBTable(nameTable, options, schema, ownerTable, dependencies, commentTable); + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } - while(rs.next()){ - String nameTable = rs.getString("tableName"); - table = new DBTable(nameTable); - table.setSchema(schema); - rowToProperties(rs, table.getOptions()); - } - return table; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public Map getTableFields(String schema, String nameTable) { - Map listField = new HashMap<>(); - try(Statement stmt = getConnection().createStatement()) { - String query = - "SELECT DISTINCT\n" + - " c.TABLE_SCHEMA as schemaName,\n" + - " c.TABLE_NAME as tableName,\n" + - " c.COLUMN_NAME as columnName,\n" + - " c.ORDINAL_POSITION as columnOrder,\n" + - " c.DATA_TYPE as mssqlType,\n" + - " CASE WHEN lower(c.DATA_TYPE) in ('bigint', 'int', 'float', 'decimal', 'money', 'numeric', 'real', 'smallint', 'smallmoney', 'tinyint') then 'number' \n" + - " when lower(c.DATA_TYPE) in ('char','varchar','xml','nchar','nvarchar', 'uniqueidentifier') then 'string'\n" + - " when lower(c.DATA_TYPE) in ('bit') then 'boolean'\n" + - " when lower(c.DATA_TYPE) in ('datetime', 'smalldatetime', 'time') then 'date'\n" + - " when lower(c.DATA_TYPE) in ('text','ntext') then 'text'\n" + - " when lower(c.DATA_TYPE) in ('timestamp', 'binary', 'varbinary', 'geometry', 'geography') then 'binary'\n" + - " else 'native'\n" + - " end dbgitType,\n" + - " CASE WHEN 1 IN ( \n" + - " SELECT OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)),'IsPrimaryKey')\n" + - " FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE\n" + - " WHERE c.COLUMN_NAME = COLUMN_NAME AND c.TABLE_NAME = TABLE_NAME\n" + - " )\n" + - " THEN 1 ELSE 0 END isPk,\n" + - " c.IS_NULLABLE as isNullable,\n" + - " c.NUMERIC_SCALE as scale,\n" + - " c.CHARACTER_MAXIMUM_LENGTH as length,\n" + - " CASE WHEN lower(c.DATA_TYPE) in ('char', 'nchar') then '1' else '0' end isFixed," + - " c.NUMERIC_PRECISION as precision\n" + - "FROM INFORMATION_SCHEMA.COLUMNS as c\n" + - "WHERE TABLE_SCHEMA = '" + schema + "' AND TABLE_NAME = '" + nameTable + "'"; + final Map listField = new HashMap<>(); + final String query = + "SELECT DISTINCT\n" + + " c.TABLE_SCHEMA as schemaName,\n" + + " c.TABLE_NAME as tableName,\n" + + " c.COLUMN_NAME as columnName,\n" + + " c.ORDINAL_POSITION as columnOrder,\n" + + " c.DATA_TYPE as mssqlType,\n" + + " CASE WHEN lower(c.DATA_TYPE) in ('bigint', 'int', 'float', 'decimal', 'money', 'numeric', 'real', 'smallint', 'smallmoney', 'tinyint') then 'number' \n" + + " when lower(c.DATA_TYPE) in ('char','varchar','xml','nchar','nvarchar', 'uniqueidentifier') then 'string'\n" + + " when lower(c.DATA_TYPE) in ('bit') then 'boolean'\n" + + " when lower(c.DATA_TYPE) in ('datetime', 'smalldatetime', 'time') then 'date'\n" + + " when lower(c.DATA_TYPE) in ('text','ntext') then 'text'\n" + + " when lower(c.DATA_TYPE) in ('timestamp', 'binary', 'varbinary', 'geometry', 'geography') then 'binary'\n" + + " else 'native'\n" + + " end dbgitType,\n" + + " CASE WHEN 1 IN ( \n" + + " SELECT OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)),'IsPrimaryKey')\n" + + " FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE\n" + + " WHERE c.COLUMN_NAME = COLUMN_NAME AND c.TABLE_NAME = TABLE_NAME\n" + + " )\n" + + " THEN 1 ELSE 0 END isPk,\n" + + " c.IS_NULLABLE as isNullable,\n" + + " c.NUMERIC_SCALE as scale,\n" + + " c.CHARACTER_MAXIMUM_LENGTH as length,\n" + + " CASE WHEN lower(c.DATA_TYPE) in ('char', 'nchar') then '1' else '0' end isFixed," + + " c.NUMERIC_PRECISION as precision\n" + + "FROM INFORMATION_SCHEMA.COLUMNS as c\n" + + "WHERE TABLE_SCHEMA = '" + schema + "' AND TABLE_NAME = '" + nameTable + "'"; + + try(Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { - ResultSet rs = stmt.executeQuery(query); while(rs.next()){ - DBTableField field = DBTableFieldFromRs(rs); + final DBTableField field = DBTableFieldFromRs(rs); listField.put(field.getName(), field); } - return listField; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + + return listField; } private DBTableField DBTableFieldFromRs(ResultSet rs) throws SQLException { - DBTableField field = new DBTableField(); - field.setName(rs.getString("columnName").toLowerCase()); - if (rs.getString("isPk").equals("1")) { - field.setIsPrimaryKey(true); - } - field.setTypeSQL(getFieldType(rs)); - field.setTypeUniversal(FieldType.fromString(rs.getString("dbgitType").toUpperCase())); - field.setLength(rs.getInt("length")); - field.setScale(rs.getInt("scale")); - field.setPrecision(rs.getInt("precision")); - field.setFixed(rs.getBoolean("isFixed")); - field.setOrder(rs.getInt("columnOrder")); - return field; + final boolean isPrimaryKey = rs.getString("isPk").equals("1"); + final boolean isFixed = rs.getBoolean("isFixed"); + final boolean isNullable = rs.getBoolean("isNullable"); + final String columnName = rs.getString("columnName").toLowerCase(); + //TODO make find out column comment + final String columnDesc = ""; + //TODO make find out column default value + final String columnDefault = ""; + final String typeSQL = getFieldType(rs); + final FieldType typeUniversal = FieldType.fromString(rs.getString("dbgitType").toUpperCase()); + final int length = rs.getInt("length"); + final int scale = rs.getInt("scale"); + final int precision = rs.getInt("precision"); + final int order = rs.getInt("order"); + + return new DBTableField( + columnName, + columnDesc == null ? "" : columnDesc, + isPrimaryKey, isNullable, + typeSQL, typeUniversal, order, + columnDefault == null ? "" : columnDefault, + length, precision, scale, isFixed + ); + } - protected String getFieldType(ResultSet rs) { - try { - StringBuilder type = new StringBuilder(); - type.append(rs.getString("mssqlType")); + protected String getFieldType(ResultSet rs) throws SQLException { - Integer max_length = rs.getInt("length"); - if (!rs.wasNull()) { - type.append("("+max_length.toString()+")"); - } - if (rs.getString("isNullable").equals("NO")){ - type.append(" NOT NULL"); - } + final StringBuilder type = new StringBuilder(); + final Integer max_length = rs.getInt("length"); + final String mssqlType = rs.getString("mssqlType"); + final boolean isNotNull = rs.getString("isNullable").equals("NO"); - return type.toString(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + type.append(mssqlType); + if (!rs.wasNull()) { + type.append("("+max_length.toString()+")"); + } + if (isNotNull){ + type.append(" NOT NULL"); } + + return type.toString(); + } public Map getIndexesWithPks(String schema, String nameTable) { - Map indexes = new HashMap<>(); - try (Statement stmt = getConnection().createStatement()){ - String query = - " SELECT DB_NAME() AS databaseName,\n" + - " sc.name as schemaName, \n" + - " t.name AS tableName,\n" + - " col.name as columnName,\n" + - " si.name AS indexName,\n" + - " si.is_primary_key isPk," + - " si.index_id as indexId,\n" + - " si.type_desc as typeName, \n" + - " CASE si.index_id WHEN 0 THEN NULL\n" + - " ELSE \n" + - " CASE is_primary_key WHEN 1 THEN\n" + - " N'ALTER TABLE ' + QUOTENAME(sc.name) + N'.' + QUOTENAME(t.name) + N' ADD CONSTRAINT ' + QUOTENAME(si.name) + N' PRIMARY KEY ' +\n" + - " CASE WHEN si.index_id > 1 THEN N'NON' ELSE N'' END + N'CLUSTERED '\n" + - " ELSE N'CREATE ' + \n" + - " CASE WHEN si.is_unique = 1 then N'UNIQUE ' ELSE N'' END +\n" + - " CASE WHEN si.index_id > 1 THEN N'NON' ELSE N'' END + N'CLUSTERED ' +\n" + - " N'INDEX ' + QUOTENAME(si.name) + N' ON ' + QUOTENAME(sc.name) + N'.' + QUOTENAME(t.name) + N' '\n" + - " END +\n" + - " /* key def */ N'(' + key_definition + N')' +\n" + - " /* includes */ CASE WHEN include_definition IS NOT NULL THEN \n" + - " N' INCLUDE (' + include_definition + N')'\n" + - " ELSE N''\n" + - " END +\n" + - " /* filters */ CASE WHEN filter_definition IS NOT NULL THEN \n" + - " N' WHERE ' + filter_definition ELSE N''\n" + - " END +\n" + - " /* with clause - compression goes here */\n" + - " CASE WHEN row_compression_partition_list IS NOT NULL OR page_compression_partition_list IS NOT NULL \n" + - " THEN N' WITH (' +\n" + - " CASE WHEN row_compression_partition_list IS NOT NULL THEN\n" + - " N'DATA_COMPRESSION = ROW ' + CASE WHEN psc.name IS NULL THEN N'' ELSE + N' ON PARTITIONS (' + row_compression_partition_list + N')' END\n" + - " ELSE N'' END +\n" + - " CASE WHEN row_compression_partition_list IS NOT NULL AND page_compression_partition_list IS NOT NULL THEN N', ' ELSE N'' END +\n" + - " CASE WHEN page_compression_partition_list IS NOT NULL THEN\n" + - " N'DATA_COMPRESSION = PAGE ' + CASE WHEN psc.name IS NULL THEN N'' ELSE + N' ON PARTITIONS (' + page_compression_partition_list + N')' END\n" + - " ELSE N'' END\n" + - " + N')'\n" + - " ELSE N''\n" + - " END +\n" + - " ' ON ' + CASE WHEN psc.name is null \n" + - " THEN ISNULL(QUOTENAME(fg.name),N'')\n" + - " ELSE psc.name + N' (' + partitioning_column.column_name + N')' \n" + - " END\n" + - " + N';'\n" + - " END AS ddl,\n" + - " si.has_filter,\n" + - " si.is_unique,\n" + - " ISNULL(pf.name, NULL) AS partition_function,\n" + - " ISNULL(psc.name, fg.name) AS partition_scheme_or_filegroup\n" + - "FROM sys.indexes AS si \n" + - "JOIN sys.index_columns ic ON si.object_id = ic.object_id and si.index_id = ic.index_id \n" + - "JOIN sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id \n" + - "JOIN sys.tables AS t ON si.object_id=t.object_id\n" + - "JOIN sys.schemas AS sc ON t.schema_id=sc.schema_id\n" + - "LEFT JOIN sys.dm_db_index_usage_stats AS stat ON \n" + - " stat.database_id = DB_ID() \n" + - " and si.object_id=stat.object_id \n" + - " and si.index_id=stat.index_id\n" + - "LEFT JOIN sys.partition_schemes AS psc ON si.data_space_id=psc.data_space_id\n" + - "LEFT JOIN sys.partition_functions AS pf ON psc.function_id=pf.function_id\n" + - "LEFT JOIN sys.filegroups AS fg ON si.data_space_id=fg.data_space_id\n" + - "OUTER APPLY ( SELECT STUFF (\n" + - " (SELECT N', ' + QUOTENAME(c.name) +\n" + - " CASE ic.is_descending_key WHEN 1 then N' DESC' ELSE N'' END\n" + - " FROM sys.index_columns AS ic \n" + - " JOIN sys.columns AS c ON \n" + - " ic.column_id=c.column_id \n" + - " and ic.object_id=c.object_id\n" + - " WHERE ic.object_id = si.object_id\n" + - " and ic.index_id=si.index_id\n" + - " and ic.key_ordinal > 0\n" + - " ORDER BY ic.key_ordinal FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,2,'')) AS keys ( key_definition )\n" + - "OUTER APPLY (\n" + - " SELECT MAX(QUOTENAME(c.name)) AS column_name\n" + - " FROM sys.index_columns AS ic \n" + - " JOIN sys.columns AS c ON \n" + - " ic.column_id=c.column_id \n" + - " and ic.object_id=c.object_id\n" + - " WHERE ic.object_id = si.object_id\n" + - " and ic.index_id=si.index_id\n" + - " and ic.partition_ordinal = 1) AS partitioning_column\n" + - "OUTER APPLY ( SELECT STUFF (\n" + - " (SELECT N', ' + QUOTENAME(c.name)\n" + - " FROM sys.index_columns AS ic \n" + - " JOIN sys.columns AS c ON \n" + - " ic.column_id=c.column_id \n" + - " and ic.object_id=c.object_id\n" + - " WHERE ic.object_id = si.object_id\n" + - " and ic.index_id=si.index_id\n" + - " and ic.is_included_column = 1\n" + - " ORDER BY c.name FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,2,'')) AS includes ( include_definition )\n" + - "OUTER APPLY ( SELECT STUFF (\n" + - " (SELECT N', ' + CAST(p.partition_number AS VARCHAR(32))\n" + - " FROM sys.partitions AS p\n" + - " WHERE p.object_id = si.object_id\n" + - " and p.index_id=si.index_id\n" + - " and p.data_compression = 1\n" + - " ORDER BY p.partition_number FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,2,'')) AS row_compression_clause ( row_compression_partition_list )\n" + - "OUTER APPLY ( SELECT STUFF (\n" + - " (SELECT N', ' + CAST(p.partition_number AS VARCHAR(32))\n" + - " FROM sys.partitions AS p\n" + - " WHERE p.object_id = si.object_id\n" + - " and p.index_id=si.index_id\n" + - " and p.data_compression = 2\n" + - " ORDER BY p.partition_number FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,2,'')) AS page_compression_clause ( page_compression_partition_list )\n" + - "WHERE si.type IN (1,2) /* clustered, nonclustered */\n" + + final Map indexes = new HashMap<>(); + final String query = + " SELECT DB_NAME() AS databaseName,\n" + + " sc.name as schemaName, \n" + + " t.name AS tableName,\n" + + " col.name as columnName,\n" + + " si.name AS indexName,\n" + + " si.is_primary_key isPk," + + " si.index_id as indexId,\n" + + " si.type_desc as typeName, \n" + + " CASE si.index_id WHEN 0 THEN NULL\n" + + " ELSE \n" + + " CASE is_primary_key WHEN 1 THEN\n" + + " N'ALTER TABLE ' + QUOTENAME(sc.name) + N'.' + QUOTENAME(t.name) + N' ADD CONSTRAINT ' + QUOTENAME(si.name) + N' PRIMARY KEY ' +\n" + + " CASE WHEN si.index_id > 1 THEN N'NON' ELSE N'' END + N'CLUSTERED '\n" + + " ELSE N'CREATE ' + \n" + + " CASE WHEN si.is_unique = 1 then N'UNIQUE ' ELSE N'' END +\n" + + " CASE WHEN si.index_id > 1 THEN N'NON' ELSE N'' END + N'CLUSTERED ' +\n" + + " N'INDEX ' + QUOTENAME(si.name) + N' ON ' + QUOTENAME(sc.name) + N'.' + QUOTENAME(t.name) + N' '\n" + + " END +\n" + + " /* key def */ N'(' + key_definition + N')' +\n" + + " /* includes */ CASE WHEN include_definition IS NOT NULL THEN \n" + + " N' INCLUDE (' + include_definition + N')'\n" + + " ELSE N''\n" + + " END +\n" + + " /* filters */ CASE WHEN filter_definition IS NOT NULL THEN \n" + + " N' WHERE ' + filter_definition ELSE N''\n" + + " END +\n" + + " /* with clause - compression goes here */\n" + + " CASE WHEN row_compression_partition_list IS NOT NULL OR page_compression_partition_list IS NOT NULL \n" + + " THEN N' WITH (' +\n" + + " CASE WHEN row_compression_partition_list IS NOT NULL THEN\n" + + " N'DATA_COMPRESSION = ROW ' + CASE WHEN psc.name IS NULL THEN N'' ELSE + N' ON PARTITIONS (' + row_compression_partition_list + N')' END\n" + + " ELSE N'' END +\n" + + " CASE WHEN row_compression_partition_list IS NOT NULL AND page_compression_partition_list IS NOT NULL THEN N', ' ELSE N'' END +\n" + + " CASE WHEN page_compression_partition_list IS NOT NULL THEN\n" + + " N'DATA_COMPRESSION = PAGE ' + CASE WHEN psc.name IS NULL THEN N'' ELSE + N' ON PARTITIONS (' + page_compression_partition_list + N')' END\n" + + " ELSE N'' END\n" + + " + N')'\n" + + " ELSE N''\n" + + " END +\n" + + " ' ON ' + CASE WHEN psc.name is null \n" + + " THEN ISNULL(QUOTENAME(fg.name),N'')\n" + + " ELSE psc.name + N' (' + partitioning_column.column_name + N')' \n" + + " END\n" + + " + N';'\n" + + " END AS ddl,\n" + + " si.has_filter,\n" + + " si.is_unique,\n" + + " ISNULL(pf.name, NULL) AS partition_function,\n" + + " ISNULL(psc.name, fg.name) AS partition_scheme_or_filegroup\n" + + "FROM sys.indexes AS si \n" + + "JOIN sys.index_columns ic ON si.object_id = ic.object_id and si.index_id = ic.index_id \n" + + "JOIN sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id \n" + + "JOIN sys.tables AS t ON si.object_id=t.object_id\n" + + "JOIN sys.schemas AS sc ON t.schema_id=sc.schema_id\n" + + "LEFT JOIN sys.dm_db_index_usage_stats AS stat ON \n" + + " stat.database_id = DB_ID() \n" + + " and si.object_id=stat.object_id \n" + + " and si.index_id=stat.index_id\n" + + "LEFT JOIN sys.partition_schemes AS psc ON si.data_space_id=psc.data_space_id\n" + + "LEFT JOIN sys.partition_functions AS pf ON psc.function_id=pf.function_id\n" + + "LEFT JOIN sys.filegroups AS fg ON si.data_space_id=fg.data_space_id\n" + + "OUTER APPLY ( SELECT STUFF (\n" + + " (SELECT N', ' + QUOTENAME(c.name) +\n" + + " CASE ic.is_descending_key WHEN 1 then N' DESC' ELSE N'' END\n" + + " FROM sys.index_columns AS ic \n" + + " JOIN sys.columns AS c ON \n" + + " ic.column_id=c.column_id \n" + + " and ic.object_id=c.object_id\n" + + " WHERE ic.object_id = si.object_id\n" + + " and ic.index_id=si.index_id\n" + + " and ic.key_ordinal > 0\n" + + " ORDER BY ic.key_ordinal FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,2,'')) AS keys ( key_definition )\n" + + "OUTER APPLY (\n" + + " SELECT MAX(QUOTENAME(c.name)) AS column_name\n" + + " FROM sys.index_columns AS ic \n" + + " JOIN sys.columns AS c ON \n" + + " ic.column_id=c.column_id \n" + + " and ic.object_id=c.object_id\n" + + " WHERE ic.object_id = si.object_id\n" + + " and ic.index_id=si.index_id\n" + + " and ic.partition_ordinal = 1) AS partitioning_column\n" + + "OUTER APPLY ( SELECT STUFF (\n" + + " (SELECT N', ' + QUOTENAME(c.name)\n" + + " FROM sys.index_columns AS ic \n" + + " JOIN sys.columns AS c ON \n" + + " ic.column_id=c.column_id \n" + + " and ic.object_id=c.object_id\n" + + " WHERE ic.object_id = si.object_id\n" + + " and ic.index_id=si.index_id\n" + + " and ic.is_included_column = 1\n" + + " ORDER BY c.name FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,2,'')) AS includes ( include_definition )\n" + + "OUTER APPLY ( SELECT STUFF (\n" + + " (SELECT N', ' + CAST(p.partition_number AS VARCHAR(32))\n" + + " FROM sys.partitions AS p\n" + + " WHERE p.object_id = si.object_id\n" + + " and p.index_id=si.index_id\n" + + " and p.data_compression = 1\n" + + " ORDER BY p.partition_number FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,2,'')) AS row_compression_clause ( row_compression_partition_list )\n" + + "OUTER APPLY ( SELECT STUFF (\n" + + " (SELECT N', ' + CAST(p.partition_number AS VARCHAR(32))\n" + + " FROM sys.partitions AS p\n" + + " WHERE p.object_id = si.object_id\n" + + " and p.index_id=si.index_id\n" + + " and p.data_compression = 2\n" + + " ORDER BY p.partition_number FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,2,'')) AS page_compression_clause ( page_compression_partition_list )\n" + + "WHERE si.type IN (1,2) /* clustered, nonclustered */\n" + // "AND si.is_primary_key = 0 /* no PKs */\n" + - "AND si.is_hypothetical = 0 /* bugged feature, always better to delete, no need to store and reconstruct them */\n" + - "AND upper(t.name) = upper('" + nameTable + "') AND upper(sc.name) = upper('" + schema + "')" + - "OPTION (RECOMPILE);"; + "AND si.is_hypothetical = 0 /* bugged feature, always better to delete, no need to store and reconstruct them */\n" + + "AND upper(t.name) = upper('" + nameTable + "') AND upper(sc.name) = upper('" + schema + "')" + + "OPTION (RECOMPILE);"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ - ResultSet rs = stmt.executeQuery(query); while(rs.next()){ - DBIndex index = new DBIndex(); - index.setName(rs.getString("indexName")); - index.setSchema(schema); - rowToProperties(rs, index.getOptions()); + final String name = rs.getString("indexName"); + final String owner = rs.getString("owner"); + final String sql = rs.getString("ddl"); + final DBIndex index = new DBIndex(name, new StringProperties(rs), schema, owner, Collections.emptySet(), sql); + indexes.put(index.getName(), index); } return indexes; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "indexes").toString()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "indexes").toString(), e); + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "indexes").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public Map getIndexes(String schema, String nameTable){ - Map indexes = getIndexesWithPks(schema, nameTable); + final Map indexes = getIndexesWithPks(schema, nameTable); + indexes.values().removeIf(x->x.getOptions().getChildren().get("ispk").getData().equals("1")); return indexes; } @Override public Map getConstraints(String schema, String nameTable) { - Map constraints = new HashMap<>(); - ArrayList queries = new ArrayList<>(); + final Map constraints = new HashMap<>(); + final ArrayList queries = new ArrayList<>(); //TODO [] in object names //check - queries.add("SELECT sc.name as schemaName, t.name as tableName, col.name as columnName, c.name as constraintName, c.name as indexName, c.type_desc as constraintType, \n" + - "'ALTER TABLE ' + sc.name + '.' + t.name + ' ADD CONSTRAINT ' + c.name + ' CHECK ' + c.definition + ';' as ddl\n" + - "FROM sys.check_constraints c\n" + - "JOIN sys.tables t ON c.parent_object_id = t.object_id \n" + - "LEFT OUTER JOIN sys.columns col on col.column_id = c.parent_column_id AND col.object_id = c.parent_object_id\n" + - "JOIN sys.schemas AS sc ON t.schema_id=sc.schema_id \n" + - "WHERE t.name = ? AND sc.name = ?"); + queries.add( + "SELECT sc.name as schemaName, t.name as tableName, col.name as columnName, c.name as constraintName, c.name as indexName, c.type_desc as constraintType, \n" + + "'ALTER TABLE ' + sc.name + '.' + t.name + ' ADD CONSTRAINT ' + c.name + ' CHECK ' + c.definition + ';' as ddl\n" + + "FROM sys.check_constraints c\n" + + "JOIN sys.tables t ON c.parent_object_id = t.object_id \n" + + "LEFT OUTER JOIN sys.columns col on col.column_id = c.parent_column_id AND col.object_id = c.parent_object_id\n" + + "JOIN sys.schemas AS sc ON t.schema_id=sc.schema_id \n" + + "WHERE t.name = :name AND sc.name = :schema"); //default - queries.add("SELECT sc.name AS schemaName, t.name AS tableName, col.name AS columnName, c.name AS constraintName, c.type_desc AS constraintType, \n" + - "'ALTER TABLE ' + sc.name + '.' + t.name + ' ADD CONSTRAINT ' + c.name+ ' DEFAULT ' \n" + - " + CASE WHEN ISNUMERIC(ic.COLUMN_DEFAULT) = 1 \n" + - " THEN TRY_CONVERT(nvarchar, TRY_CONVERT(numeric, ic.COLUMN_DEFAULT))\n" + - " ELSE '' + ic.COLUMN_DEFAULT + '' END\n" + - " + ' FOR [' + col.name + '];' AS ddl\n" + - "FROM sys.default_constraints c\n" + - "JOIN sys.tables t ON c.parent_object_id = t.object_id \n" + - "JOIN sys.columns col ON col.default_object_id = c.object_id\n" + - "JOIN sys.schemas AS sc ON t.schema_id=sc.schema_id \n" + - "JOIN INFORMATION_SCHEMA.COLUMNS ic on t.name = ic.TABLE_NAME AND col.name = ic.COLUMN_NAME \n" + - "WHERE t.name = ? AND sc.name = ?\n"); + queries.add( + "SELECT sc.name AS schemaName, t.name AS tableName, col.name AS columnName, c.name AS constraintName, c.type_desc AS constraintType, \n" + + "'ALTER TABLE ' + sc.name + '.' + t.name + ' ADD CONSTRAINT ' + c.name+ ' DEFAULT ' \n" + + " + CASE WHEN ISNUMERIC(ic.COLUMN_DEFAULT) = 1 \n" + + " THEN TRY_CONVERT(nvarchar, TRY_CONVERT(numeric, ic.COLUMN_DEFAULT))\n" + + " ELSE '' + ic.COLUMN_DEFAULT + '' END\n" + + " + ' FOR [' + col.name + '];' AS ddl\n" + + "FROM sys.default_constraints c\n" + + "JOIN sys.tables t ON c.parent_object_id = t.object_id \n" + + "JOIN sys.columns col ON col.default_object_id = c.object_id\n" + + "JOIN sys.schemas AS sc ON t.schema_id=sc.schema_id \n" + + "JOIN INFORMATION_SCHEMA.COLUMNS ic on t.name = ic.TABLE_NAME AND col.name = ic.COLUMN_NAME \n" + + "WHERE t.name = :name AND sc.name = :schema\n" + ); //unique - queries.add("SELECT TC.TABLE_SCHEMA AS schemaName, TC.TABLE_NAME AS tableName, CC.Column_Name AS columnName, TC.Constraint_Name AS constraintName, TC.CONSTRAINT_TYPE AS constraintType,\n" + - "'ALTER TABLE ' + TC.TABLE_SCHEMA + '.' + TC.TABLE_NAME + ' ADD CONSTRAINT ' + TC.CONSTRAINT_NAME + ' UNIQUE NONCLUSTERED ([' + CC.COLUMN_NAME + ']);' AS ddl\n" + - "FROM INFORMATION_SCHEMA.table_constraints TC\n" + - "INNER JOIN INFORMATION_SCHEMA.constraint_column_usage CC on TC.Constraint_Name = CC.Constraint_Name\n" + - "WHERE TC.constraint_type = 'Unique' AND TC.TABLE_NAME = ? AND TC.TABLE_SCHEMA = ? ---- PARAMETER 1,2\n"); + queries.add( + "SELECT TC.TABLE_SCHEMA AS schemaName, TC.TABLE_NAME AS tableName, CC.Column_Name AS columnName, TC.Constraint_Name AS constraintName, TC.CONSTRAINT_TYPE AS constraintType,\n" + + "'ALTER TABLE ' + TC.TABLE_SCHEMA + '.' + TC.TABLE_NAME + ' ADD CONSTRAINT ' + TC.CONSTRAINT_NAME + ' UNIQUE NONCLUSTERED ([' + CC.COLUMN_NAME + ']);' AS ddl\n" + + "FROM INFORMATION_SCHEMA.table_constraints TC\n" + + "INNER JOIN INFORMATION_SCHEMA.constraint_column_usage CC on TC.Constraint_Name = CC.Constraint_Name\n" + + "WHERE TC.constraint_type = 'Unique' AND TC.TABLE_NAME = :name AND TC.TABLE_SCHEMA = :schema ---- PARAMETER 1,2\n" + ); //foreign - queries.add("SELECT ss.name as schemaName, t.name as tableName, sc.name as columnName, o.name as constraintName, o.type_desc as constraintType, refss.name as refSchemaName, refst.name as refTableName, refsc.name as refColumnName, " + - "'ALTER TABLE ' + ss.name + '.' + t.name + ' ADD CONSTRAINT ' + o.name + ' FOREIGN KEY ('+ sc.name + ') references ' + refss.name + '.' + refst.name + '(' + refsc.name + ');' as ddl\n" + - "FROM sys.foreign_key_columns c\n" + - "JOIN sys.objects o ON c.constraint_object_id = o.object_id\n" + - "LEFT OUTER JOIN sys.tables t on t.object_id = c.parent_object_id \n" + - "LEFT OUTER JOIN sys.schemas ss on ss.schema_id = o.schema_id \n" + - "LEFT OUTER JOIN sys.columns sc on sc.object_id = c.parent_object_id AND sc.column_id = c.parent_column_id\n" + - "LEFT OUTER JOIN sys.tables refst on refst.object_id = c.referenced_object_id\n" + - "LEFT OUTER JOIN sys.schemas refss on refss.schema_id = refst.schema_id\n" + - "LEFT OUTER JOIN sys.columns refsc on refsc.object_id = c.referenced_object_id AND refsc.column_id = c.referenced_column_id \n" + - "WHERE t.name = ? AND ss.name = ?\n" + queries.add( + "SELECT ss.name as schemaName, t.name as tableName, sc.name as columnName, o.name as constraintName, o.type_desc as constraintType, refss.name as refSchemaName, refst.name as refTableName, refsc.name as refColumnName, " + + "'ALTER TABLE ' + ss.name + '.' + t.name + ' ADD CONSTRAINT ' + o.name + ' FOREIGN KEY ('+ sc.name + ') references ' + refss.name + '.' + refst.name + '(' + refsc.name + ');' as ddl\n" + + "FROM sys.foreign_key_columns c\n" + + "JOIN sys.objects o ON c.constraint_object_id = o.object_id\n" + + "LEFT OUTER JOIN sys.tables t on t.object_id = c.parent_object_id \n" + + "LEFT OUTER JOIN sys.schemas ss on ss.schema_id = o.schema_id \n" + + "LEFT OUTER JOIN sys.columns sc on sc.object_id = c.parent_object_id AND sc.column_id = c.parent_column_id\n" + + "LEFT OUTER JOIN sys.tables refst on refst.object_id = c.referenced_object_id\n" + + "LEFT OUTER JOIN sys.schemas refss on refss.schema_id = refst.schema_id\n" + + "LEFT OUTER JOIN sys.columns refsc on refsc.object_id = c.referenced_object_id AND refsc.column_id = c.referenced_column_id \n" + + "WHERE t.name = :name AND ss.name = :schema\n" ); + final Iterator it = queries.iterator(); + while (it.hasNext()) { + final String query = it.next(); + try ( + PreparedStatement stmt = preparedStatement(getConnection(), query, ImmutableMap.of("name", nameTable, "schema" , schema)); + ResultSet rs = stmt.executeQuery(query); + ){ - Iterator it = queries.iterator(); - try { - while (it.hasNext()) { - String query = it.next(); - PreparedStatement stmt = connect.prepareStatement(query); - stmt.setString(2, schema); - stmt.setString(1, nameTable); - ResultSet rs = stmt.executeQuery(); - - - while (rs.next()) { - DBConstraint con = new DBConstraint(); - con.setName(rs.getString("constraintName")); - con.setConstraintType(rs.getString("constraintType")); - con.setSchema(schema); - rowToProperties(rs, con.getOptions()); - constraints.put(con.getName(), con); - } - stmt.close(); - } + while (rs.next()) { + final String name = rs.getString("constraintName"); + final String type = rs.getString("constraintType"); + final String sql = rs.getString("ddl"); + final String owner = schema; - //primary keys - Map indexes = getIndexesWithPks(schema, nameTable); - indexes.values().removeIf(x->x.getOptions().getChildren().get("ispk").getData().equals("0")); - for(DBIndex pki:indexes.values()){ - DBConstraint pkc = new DBConstraint(); - pkc.setName(pki.getName()); - pkc.setConstraintType(pki.getOptions().getChildren().get("typename").getData()); - pkc.setSchema(pki.getSchema()); - pkc.setOptions(pki.getOptions()); - constraints.put(pkc.getName(), pkc); + final DBConstraint con = new DBConstraint(name, new StringProperties(rs), schema, owner, Collections.emptySet(), sql, type); + constraints.put(con.getName(), con); + } + } catch (Exception ex){ + final String msg = lang.getValue("errors", "adapter", "constraints").toString(); + throw new ExceptionDBGitRunTime(msg, ex); } + } + + //primary keys + final Map indexes = getIndexesWithPks(schema, nameTable); + indexes.values().removeIf(x->x.getOptions().getChildren().get("ispk").getData().equals("0")); + + for( DBIndex pki : indexes.values() ){ + final String constraintType = pki.getOptions().getChildren().get("typename").getData(); + final DBConstraint pkc = new DBConstraint( + pki.getName(), + pki.getOptions(), + pki.getSchema(), + pki.getOwner(), + new HashSet<>(pki.getDependencies()), + pki.getSql(), + constraintType + ); + pkc.setOptions(pki.getOptions()); + constraints.put(pkc.getName(), pkc); + } - return constraints; + return constraints; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "constraints").toString()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "constraints").toString(), e); - } } @Override public Map getViews(String schema) { - Map listView = new HashMap(); - try (Statement stmt = getConnection().createStatement()){ - String query = - "SELECT \n" + - " sp.name as ownerName, sp.type_desc as ownerType, ss.name AS schemaName, sv.name AS viewName, sm.definition as ddl, \n" + - " sv.type_desc as typeName, sm.uses_ansi_nulls, sm.uses_quoted_identifier, sm.is_schema_bound, \n" + - " OBJECTPROPERTYEX(sv.object_id,'IsIndexable') AS IsIndexable,\n" + - " OBJECTPROPERTYEX(sv.object_id,'IsIndexed') AS IsIndexed\n" + - "FROM sys.views sv\n" + - "JOIN sys.schemas ss ON sv.schema_id = ss.schema_id\n" + - "LEFT OUTER JOIN sys.sql_modules sm on sv.object_id = sm.object_id\n" + - "LEFT OUTER JOIN sys.database_principals sp on sv.principal_id = sp.principal_id"; - - ResultSet rs = stmt.executeQuery(query); + final Map listView = new HashMap(); + final String query = + "SELECT \n" + + " sp.name as ownerName, sp.type_desc as ownerType, ss.name AS schemaName, sv.name AS viewName, sm.definition as ddl, \n" + + " sv.type_desc as typeName, sm.uses_ansi_nulls, sm.uses_quoted_identifier, sm.is_schema_bound, \n" + + " OBJECTPROPERTYEX(sv.object_id,'IsIndexable') AS IsIndexable,\n" + + " OBJECTPROPERTYEX(sv.object_id,'IsIndexed') AS IsIndexed\n" + + "FROM sys.views sv\n" + + "JOIN sys.schemas ss ON sv.schema_id = ss.schema_id\n" + + "LEFT OUTER JOIN sys.sql_modules sm on sv.object_id = sm.object_id\n" + + "LEFT OUTER JOIN sys.database_principals sp on sv.principal_id = sp.principal_id"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ - DBView view = new DBView(rs.getString("viewName")); - view.setSchema(rs.getString("schemaName")); - view.setOwner(rs.getString("ownerName")); - rowToProperties(rs, view.getOptions()); - listView.put(rs.getString("viewName"), view); + final String name = rs.getString("viewName"); + final String schemaName = rs.getString("schemaName"); + final String owner = rs.getString("ownerName"); + final String sql = rs.getString("ddl"); + + final DBView view = new DBView(name, new StringProperties(rs), schema, owner, Collections.emptySet(), sql); + listView.put(name, view); } return listView; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "views") + ": "+ e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "views") + ": " + e.getMessage()); + + } catch(Exception e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "views"); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public DBView getView(String schema, String name) { + //TODO single-version query with ExceptionDBGitNotFound try { return getViews(schema).get(name); - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "views").toString() + ": "+ e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "views").toString() + ": "+ e.getMessage()); + } catch(Exception e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "views"); + throw new ExceptionDBGitRunTime(msg, e); } } @@ -665,127 +687,124 @@ public Map getPackages(String schema) { @Override public DBPackage getPackage(String schema, String name) { // No such implementation in MSSQL - return null; + throw new ExceptionDBGitRunTime(new ExceptionDBGitObjectNotFound("cannot get packages on mssql")); } @Override public Map getProcedures(String schema) { - Map listProcedure = new HashMap(); - try (Statement stmt = getConnection().createStatement()){ - String query = - "SELECT s.name schemaName, o.name procedureName, o.type_desc as typeName, definition ddl, USER_NAME(so.uid) AS owner \n" + - "FROM sys.sql_modules m\n" + - "JOIN sys.procedures p ON m.object_id = p.object_id\n" + - "JOIN sys.objects o \n" + - " ON o.object_id = p.object_id \n" + - " AND Left(o.name, 3) NOT IN ('sp_', 'xp_', 'ms_') \n" + - "JOIN sys.schemas s ON s.schema_id = o.schema_id\n" + - "JOIN sysobjects so on o.object_id = so.id\n" + - "WHERE s.name = '" + schema + "'\n"; - - ResultSet rs = stmt.executeQuery(query); + final Map listProcedure = new HashMap(); + final String query = + "SELECT s.name schemaName, o.name procedureName, o.type_desc as typeName, definition ddl, USER_NAME(so.uid) AS owner \n" + + "FROM sys.sql_modules m\n" + + "JOIN sys.procedures p ON m.object_id = p.object_id\n" + + "JOIN sys.objects o \n" + + " ON o.object_id = p.object_id \n" + + " AND Left(o.name, 3) NOT IN ('sp_', 'xp_', 'ms_') \n" + + "JOIN sys.schemas s ON s.schema_id = o.schema_id\n" + + "JOIN sysobjects so on o.object_id = so.id\n" + + "WHERE s.name = '" + schema + "'\n"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ while(rs.next()){ - String name = rs.getString("procedureName"); - String owner = rs.getString("owner"); - DBProcedure proc = new DBProcedure(name); - proc.setSchema(schema); - proc.setOwner(owner); - proc.setName(name); - rowToProperties(rs,proc.getOptions()); + final String name = rs.getString("procedureName"); + final String owner = rs.getString("owner"); + final String sql = rs.getString("ddl"); + final StringProperties options = new StringProperties(rs); + final DBProcedure proc = new DBProcedure(name, options, schema, owner, Collections.emptySet(), sql); listProcedure.put(name, proc); } - stmt.close(); }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "prc").toString(), e); + final String msg = lang.getValue("errors", "adapter", "prc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listProcedure; } @Override public DBProcedure getProcedure(String schema, String name) { - try (Statement stmt = getConnection().createStatement()){ - String query = - "SELECT s.name schemaName, o.name procedureName, o.type_desc as typeName, definition ddl, USER_NAME(so.uid) AS owner \n" + - "FROM sys.sql_modules m\n" + - "JOIN sys.procedures p ON m.object_id = p.object_id\n" + - "JOIN sys.objects o \n" + - " ON o.object_id = p.object_id \n" + - " AND Left(o.name, 3) NOT IN ('sp_', 'xp_', 'ms_') -- filter out system ones\n" + - "JOIN sys.schemas s ON s.schema_id = o.schema_id\n" + - "JOIN sysobjects so on o.object_id = so.id \n" + - "WHERE s.name = '" + schema + "' AND o.name = '" + name + "'"; - ResultSet rs = stmt.executeQuery(query); - DBProcedure proc = null; - - while (rs.next()) { - proc = new DBProcedure(rs.getString("procedureName")); - String owner = rs.getString("owner"); - proc.setSchema(schema); - proc.setOwner(owner); - rowToProperties(rs,proc.getOptions()); - } - stmt.close(); - - return proc; - - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "prc").toString(), e); + final String query = + "SELECT s.name schemaName, o.name procedureName, o.type_desc as typeName, definition ddl, USER_NAME(so.uid) AS owner \n" + + "FROM sys.sql_modules m\n" + + "JOIN sys.procedures p ON m.object_id = p.object_id\n" + + "JOIN sys.objects o \n" + + " ON o.object_id = p.object_id \n" + + " AND Left(o.name, 3) NOT IN ('sp_', 'xp_', 'ms_') -- filter out system ones\n" + + "JOIN sys.schemas s ON s.schema_id = o.schema_id\n" + + "JOIN sysobjects so on o.object_id = so.id \n" + + "WHERE s.name = '" + schema + "' AND o.name = '" + name + "'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + + if (!rs.next()) throw new ExceptionDBGitObjectNotFound(""); + + final String owner = rs.getString("owner"); + final String procedureName = rs.getString("procedureName"); + final String sql = rs.getString("ddl"); + final StringProperties options = new StringProperties(rs); + + return new DBProcedure(procedureName, options, schema, owner, Collections.emptySet(), sql); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "prc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public Map getFunctions(String schema) { - Map listFunction = new HashMap<>(); - try (Statement stmt = getConnection().createStatement()){ - String query = - "SELECT ss.name schemaName, o.name functionName, type_desc typeName, definition ddl, USER_NAME(so.uid) owner \n" + - "FROM sys.sql_modules m \n" + - "INNER JOIN sys.objects o ON m.object_id = o.object_id\n" + - "INNER JOIN sysobjects so ON m.object_id = so.id\n" + - "INNER JOIN sys.schemas ss ON ss.schema_id = o.schema_id\n" + - "WHERE type_desc like '%function%' AND ss.name = '" + schema + "'\n"; + final Map listFunction = new HashMap<>(); + final String query = + "SELECT ss.name schemaName, o.name functionName, type_desc typeName, definition ddl, USER_NAME(so.uid) owner \n" + + "FROM sys.sql_modules m \n" + + "INNER JOIN sys.objects o ON m.object_id = o.object_id\n" + + "INNER JOIN sysobjects so ON m.object_id = so.id\n" + + "INNER JOIN sys.schemas ss ON ss.schema_id = o.schema_id\n" + + "WHERE type_desc like '%function%' AND ss.name = '" + schema + "'\n"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ - ResultSet rs = stmt.executeQuery(query); while(rs.next()){ - String name = rs.getString("functionName"); - String owner = rs.getString("owner"); - DBFunction func = new DBFunction(name); - func.setSchema(schema); - func.setOwner(owner); - rowToProperties(rs,func.getOptions()); + final String name = rs.getString("functionName"); + final String owner = rs.getString("owner"); + final String sql = rs.getString("ddl"); + final StringProperties options = new StringProperties(rs); + + final DBFunction func = new DBFunction(name, options, schema, owner, Collections.emptySet(), sql); listFunction.put(name, func); } - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "fnc").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "fnc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listFunction; } @Override public DBFunction getFunction(String schema, String name) { - try (Statement stmt = getConnection().createStatement()){ - String query = - "SELECT ss.name schemaName, o.name functionName, type_desc typeName, definition ddl, USER_NAME(so.uid) owner \n" + - "FROM sys.sql_modules m \n" + - "INNER JOIN sys.objects o ON m.object_id = o.object_id\n" + - "INNER JOIN sysobjects so ON m.object_id = so.id\n" + - "INNER JOIN sys.schemas ss ON ss.schema_id = o.schema_id\n" + - "WHERE type_desc like '%function%' AND ss.name = '" + schema + "' AND o.name = '" + name + "'\n"; - - DBFunction func = null; - ResultSet rs = stmt.executeQuery(query); - while (rs.next()) { - func = new DBFunction(rs.getString("functionName")); - String owner = rs.getString("owner"); - func.setSchema(schema); - func.setOwner(owner); - rowToProperties(rs,func.getOptions()); - } - return func; + final String query = + "SELECT ss.name schemaName, o.name functionName, type_desc typeName, definition ddl, USER_NAME(so.uid) owner \n" + + "FROM sys.sql_modules m \n" + + "INNER JOIN sys.objects o ON m.object_id = o.object_id\n" + + "INNER JOIN sysobjects so ON m.object_id = so.id\n" + + "INNER JOIN sys.schemas ss ON ss.schema_id = o.schema_id\n" + + "WHERE type_desc like '%function%' AND ss.name = '" + schema + "' AND o.name = '" + name + "'\n"; - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "fnc").toString(), e); + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + + if (!rs.next()) throw new ExceptionDBGitObjectNotFound(""); + + final String functionName = rs.getString("functionName"); + final String owner = rs.getString("owner"); + final String sql = rs.getString("ddl"); + final StringProperties options = new StringProperties(rs); + + return new DBFunction(functionName, options, schema, owner, Collections.emptySet(), sql); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "fnc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @@ -793,134 +812,135 @@ public DBFunction getFunction(String schema, String name) { // it is not possible to get definition of an encrypted trigger public Map getTriggers(String schema) { - Map listTrigger = new HashMap(); - try (Statement stmt = getConnection().createStatement()){ - String query = - "SELECT \n" + - " s.name schemaName, \n" + - " o.name triggerName, \n" + - " USER_NAME(o.uid) owner, \n" + - " OBJECT_NAME(parent_obj) tableName, \n" + - " m.definition as ddl, \n" + - " OBJECTPROPERTY(id, 'IsEncrypted') AS encrypted \n" + - "FROM sysobjects o\n" + - "INNER JOIN sys.tables t ON o.parent_obj = t.object_id \n" + - "INNER JOIN sys.schemas s ON t.schema_id = s.schema_id \n" + - "INNER JOIN sys.sql_modules m ON m.object_id = o.id\n" + - "WHERE o.type = 'TR' AND s.name = '" + schema + "'\n"; + final Map listTrigger = new HashMap(); + final String query = + "SELECT \n" + + " s.name schemaName, \n" + + " o.name triggerName, \n" + + " USER_NAME(o.uid) owner, \n" + + " OBJECT_NAME(parent_obj) tableName, \n" + + " m.definition as ddl, \n" + + " OBJECTPROPERTY(id, 'IsEncrypted') AS encrypted \n" + + "FROM sysobjects o\n" + + "INNER JOIN sys.tables t ON o.parent_obj = t.object_id \n" + + "INNER JOIN sys.schemas s ON t.schema_id = s.schema_id \n" + + "INNER JOIN sys.sql_modules m ON m.object_id = o.id\n" + + "WHERE o.type = 'TR' AND s.name = '" + schema + "'\n"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ - ResultSet rs = stmt.executeQuery(query); while(rs.next()){ - String name = rs.getString("triggerName"); - String owner = rs.getString("owner"); - DBTrigger trigger = new DBTrigger(name); - trigger.setSchema(schema); - trigger.setOwner(owner); - // -- what means owner? oracle/postgres or owner like database user/schema - // -- IMO its a database object owner - - rowToProperties(rs, trigger.getOptions()); + final String name = rs.getString("triggerName"); + final String owner = rs.getString("owner"); + final String sql = rs.getString("ddl"); + final StringProperties options = new StringProperties(rs); + + DBTrigger trigger = new DBTrigger(name, options, schema, owner, Collections.emptySet(), sql); listTrigger.put(name, trigger); } return listTrigger; - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "triggers").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "triggers").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } public DBTrigger getTrigger(String schema, String name) { - DBTrigger trigger = null; - try (Statement stmt = getConnection().createStatement()){ - String query = - "SELECT \n" + - " s.name schemaName, \n" + - " o.name triggerName, \n" + - " USER_NAME(o.uid) owner, \n" + - " OBJECT_NAME(parent_obj) tableName, \n" + - " m.definition as ddl, \n" + - " OBJECTPROPERTY(id, 'IsEncrypted') AS encrypted \n" + - "FROM sysobjects o\n" + - "INNER JOIN sys.tables t ON o.parent_obj = t.object_id \n" + - "INNER JOIN sys.schemas s ON t.schema_id = s.schema_id \n" + - "INNER JOIN sys.sql_modules m ON m.object_id = o.id\n" + - "WHERE o.type = 'TR' AND s.name = '" + schema + "' AND o.name = '" + name + "'\n"; - - ResultSet rs = stmt.executeQuery(query); - while(rs.next()){ - String tname = rs.getString("triggerName"); - String owner = rs.getString("owner"); - trigger = new DBTrigger(tname); - trigger.setSchema(schema); - trigger.setOwner(owner); - rowToProperties(rs, trigger.getOptions()); - } - return trigger; - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "triggers").toString(), e); + final String query = + "SELECT \n" + + " s.name schemaName, \n" + + " o.name triggerName, \n" + + " USER_NAME(o.uid) owner, \n" + + " OBJECT_NAME(parent_obj) tableName, \n" + + " m.definition as ddl, \n" + + " OBJECTPROPERTY(id, 'IsEncrypted') AS encrypted \n" + + "FROM sysobjects o\n" + + "INNER JOIN sys.tables t ON o.parent_obj = t.object_id \n" + + "INNER JOIN sys.schemas s ON t.schema_id = s.schema_id \n" + + "INNER JOIN sys.sql_modules m ON m.object_id = o.id\n" + + "WHERE o.type = 'TR' AND s.name = '" + schema + "' AND o.name = '" + name + "'\n"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + + if(!rs.next()) throw new ExceptionDBGitObjectNotFound(""); + + final String tname = rs.getString("triggerName"); + final String owner = rs.getString("owner"); + final String sql = rs.getString("ddl"); + final StringProperties options = new StringProperties(rs); + + return new DBTrigger(name, options, schema, owner, Collections.emptySet(), sql); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "triggers").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public DBTableData getTableData(String schema, String nameTable) { - try { - Statement stmt = getConnection().createStatement(); - DBTableData data = new DBTableData(); + final String dataQuery = "SELECT * FROM [" + schema + "].[" + nameTable + "]"; - int maxRowsCount = DBGitConfig.getInstance().getInteger( - "core", - "MAX_ROW_COUNT_FETCH", - DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH) - ); + final int maxRowsCount = DBGitConfig.getInstance().getInteger( + "core", "MAX_ROW_COUNT_FETCH", + DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH) + ); - boolean isLimitedFetch = DBGitConfig.getInstance().getBoolean( - "core", - "LIMIT_FETCH", - DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true) - ); + final boolean isLimitedFetch = DBGitConfig.getInstance().getBoolean( + "core", "LIMIT_FETCH", + DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true) + ); - if (isLimitedFetch) - { - String query = - "SELECT COALESCE(SUM(PART.rows), 0) AS rowsCount\n" + - "FROM sys.tables TBL\n" + - "INNER JOIN sys.partitions PART ON TBL.object_id = PART.object_id\n" + - "INNER JOIN sys.indexes IDX ON PART.object_id = IDX.object_id AND PART.index_id = IDX.index_id\n" + - "INNER JOIN sys.schemas S ON S.schema_id = TBL.schema_id\n" + - "WHERE TBL.name = '"+nameTable+"' AND S.name = '"+schema+"' AND IDX.index_id < 2\n" + - "GROUP BY TBL.object_id, TBL.name"; - - ResultSet rs = stmt.executeQuery(query); - rs.next(); - if (rs.getInt("rowsCount") > maxRowsCount) { - data.setErrorFlag(DBTableData.ERROR_LIMIT_ROWS); - return data; - } - } + try{ - ResultSet rs = stmt.executeQuery("SELECT * FROM [" + schema + "].[" + nameTable + "]"); - data.setResultSet(rs); - return data; + if (isLimitedFetch) { + final String rowsCountQuery = + "SELECT COALESCE(SUM(PART.rows), 0) AS rowsCount\n" + + "FROM sys.tables TBL\n" + + "INNER JOIN sys.partitions PART ON TBL.object_id = PART.object_id\n" + + "INNER JOIN sys.indexes IDX ON PART.object_id = IDX.object_id AND PART.index_id = IDX.index_id\n" + + "INNER JOIN sys.schemas S ON S.schema_id = TBL.schema_id\n" + + "WHERE TBL.name = '"+nameTable+"' AND S.name = '"+schema+"' AND IDX.index_id < 2\n" + + "GROUP BY TBL.object_id, TBL.name"; + + try( + Statement st = getConnection().createStatement(); + ResultSet rs = st.executeQuery(rowsCountQuery); + ){ + if(!rs.next()) throw new ExceptionDBGitRunTime("rows coubt resultset is empty"); + if (rs.getInt("rowsCount") > maxRowsCount) { + return new DBTableData(DBTableData.ERROR_LIMIT_ROWS); + } + } + + } + + return new DBTableData(getConnection(), dataQuery); + + } catch (Exception e){ + final String msg = DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); + } - } catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - try { - getConnection().rollback(); - } catch (Exception e2) { - logger.error(lang.getValue("errors", "adapter", "rollback").toString(), e2); - } - throw new ExceptionDBGitRunTime(e.getMessage()); - } } @Override public DBTableData getTableDataPortion(String schema, String nameTable, int portionIndex, int tryNumber) { - DBTableData data = new DBTableData(); + + final int portionSize = DBGitConfig.getInstance().getInteger( "core", "PORTION_SIZE", + DBGitConfig.getInstance().getIntegerGlobal("core", "PORTION_SIZE", 1000) + ); + + final int dataOffset = portionSize * portionIndex; + final String dataQuery = + "SELECT * " + + "FROM " + schema + "." + nameTable + " " + + "ORDER BY (SELECT NULL) " + + "OFFSET " + dataOffset + " ROWS " + + "FETCH NEXT " + portionSize + " ROWS ONLY "; try { - Statement stmt = getConnection().createStatement(); - int portionSize = DBGitConfig.getInstance().getInteger( "core", "PORTION_SIZE", - DBGitConfig.getInstance().getIntegerGlobal("core", "PORTION_SIZE", 1000) - ); /* For version <= SQL Server 2005 @@ -936,221 +956,246 @@ public DBTableData getTableDataPortion(String schema, String nameTable, int port ); */ - ResultSet rs = stmt.executeQuery( "SELECT * " + - "FROM "+ schema + "." + nameTable + " " + - "ORDER BY (SELECT NULL) " + - "OFFSET " + portionSize*portionIndex + " ROWS " + - "FETCH NEXT " + portionSize + " ROWS ONLY " - ); + return new DBTableData(getConnection(), dataQuery); - data.setResultSet(rs); - return data; } catch (Exception e) { - ConsoleWriter.println("Connection lost!"); - ConsoleWriter.println("Error while getting portion of data, try " + tryNumber); - logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - - //try fetch again - try { + final int maxTriesCount = DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000)); + final int tryDelay = DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000)); - int retryDelay = DBGitConfig.getInstance().getInteger( "core", "TRY_DELAY", - DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000) - ); + ConsoleWriter.println(e.getLocalizedMessage(), messageLevel); + ConsoleWriter.detailsPrintln(ExceptionUtils.getStackTrace(e), messageLevel); + logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - int maxTryCount = DBGitConfig.getInstance().getInteger( "core", "TRY_COUNT", - DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000) - ); + if (tryNumber <= maxTriesCount) { - if (tryNumber <= maxTryCount) { + final String waitMessage = DBGitLang.getInstance() + .getValue("errors", "dataTable", "wait") + .withParams(String.valueOf(tryDelay)); - try { TimeUnit.SECONDS.sleep(retryDelay); } - catch (InterruptedException e1) { throw new ExceptionDBGitRunTime(e1.getMessage()); } + final String tryAgainMessage = DBGitLang.getInstance() + .getValue("errors", "dataTable", "tryAgain") + .withParams(String.valueOf(tryNumber)); - return getTableDataPortion(schema, nameTable, portionIndex, tryNumber++); + ConsoleWriter.println(waitMessage, messageLevel); + try { TimeUnit.SECONDS.sleep(tryDelay); } catch (InterruptedException e1) { + throw new ExceptionDBGitRunTime(e1.getMessage()); } - } catch (Exception e1) { e1.printStackTrace(); } - //rollback, needed only when auto-commit mode has been disabled + ConsoleWriter.println(tryAgainMessage, messageLevel); + return getTableDataPortion(schema, nameTable, portionIndex, tryNumber++); - try { - getConnection().rollback(); - } catch (Exception e2) { - logger.error(lang.getValue("errors", "adapter", "rollback").toString(), e2); + } else { + final String msg = DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); } - throw new ExceptionDBGitRunTime(e.getMessage()); } } @Override public Map getUsers() { - Map listUser = new HashMap(); - try { - - String query = - "DECLARE @crlf VARCHAR(2)\n" + - "SELECT \n" + - " u.name userName, sp.name loginName, sp.default_database_name databaseName, dp.default_schema_name as schemaName,\n" + - " CASE WHEN sp.is_disabled IS NULL THEN 1 ELSE sp.is_disabled END isDisabledLogin,\n" + - " CASE WHEN sp.name IS NOT NULL THEN 'CREATE LOGIN [' + sp.name + '] WITH PASSWORD = ' \n" + - " + UPPER(master.dbo.fn_varbintohexstr (CAST(LOGINPROPERTY(sp.name,'PASSWORDHASH') as VARBINARY (256)))) + ' HASHED; ' ELSE '' END \n" + - " + CASE WHEN sp.is_disabled IS NOT NULL AND sp.is_disabled = 0 AND dr.permission_name IS NOT NULL THEN 'GRANT CONNECT SQL TO [' + sp.name + ']; ' ELSE '' END \n" + - " + 'CREATE USER [' + u.name + '] ' \n" + - " + CASE WHEN sp.name IS NOT NULL THEN 'FOR LOGIN [' + sp.name + ']' ELSE '' END\n" + - " + CASE WHEN dp.default_schema_name IS NOT NULL THEN ' WITH DEFAULT_SCHEMA = [' + dp.default_schema_name + ']' ELSE '' END + ';' \n" + - " AS ddl, \n" + - " UPPER(master.dbo.fn_varbintohexstr (CAST(LOGINPROPERTY(sp.name,'PASSWORDHASH') as VARBINARY (256)))) passwordHash\n" + - "FROM sys.sysusers u \n" + - "INNER JOIN sys.database_principals dp ON dp.sid = u.sid\n" + - "LEFT OUTER JOIN sys.server_principals sp ON sp.sid = u.sid\n" + - "LEFT OUTER JOIN sys.database_permissions dr ON dr.grantee_principal_id = dp.principal_id AND dr.permission_name = 'CONNECT'\n" + - "WHERE dp.type_desc = 'SQL_USER' AND u.name NOT IN ('dbo','guest') AND u.name NOT LIKE '##MS%'"; - + final Map listUser = new HashMap(); + final String query = + "DECLARE @crlf VARCHAR(2)\n" + + "SELECT \n" + + " u.name userName, sp.name loginName, sp.default_database_name databaseName, dp.default_schema_name as schemaName,\n" + + " CASE WHEN sp.is_disabled IS NULL THEN 1 ELSE sp.is_disabled END isDisabledLogin,\n" + + " CASE WHEN sp.name IS NOT NULL THEN 'CREATE LOGIN [' + sp.name + '] WITH PASSWORD = ' \n" + + " + UPPER(master.dbo.fn_varbintohexstr (CAST(LOGINPROPERTY(sp.name,'PASSWORDHASH') as VARBINARY (256)))) + ' HASHED; ' ELSE '' END \n" + + " + CASE WHEN sp.is_disabled IS NOT NULL AND sp.is_disabled = 0 AND dr.permission_name IS NOT NULL THEN 'GRANT CONNECT SQL TO [' + sp.name + ']; ' ELSE '' END \n" + + " + 'CREATE USER [' + u.name + '] ' \n" + + " + CASE WHEN sp.name IS NOT NULL THEN 'FOR LOGIN [' + sp.name + ']' ELSE '' END\n" + + " + CASE WHEN dp.default_schema_name IS NOT NULL THEN ' WITH DEFAULT_SCHEMA = [' + dp.default_schema_name + ']' ELSE '' END + ';' \n" + + " AS ddl, \n" + + " UPPER(master.dbo.fn_varbintohexstr (CAST(LOGINPROPERTY(sp.name,'PASSWORDHASH') as VARBINARY (256)))) passwordHash\n" + + "FROM sys.sysusers u \n" + + "INNER JOIN sys.database_principals dp ON dp.sid = u.sid\n" + + "LEFT OUTER JOIN sys.server_principals sp ON sp.sid = u.sid\n" + + "LEFT OUTER JOIN sys.database_permissions dr ON dr.grantee_principal_id = dp.principal_id AND dr.permission_name = 'CONNECT'\n" + + "WHERE dp.type_desc = 'SQL_USER' AND u.name NOT IN ('dbo','guest') AND u.name NOT LIKE '##MS%'"; + + try ( Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ){ while(rs.next()){ - String name = rs.getString(1); - DBUser user = new DBUser(name); - rowToProperties(rs, user.getOptions()); + final String name = rs.getString(1); + final StringProperties options = new StringProperties(rs); + + DBUser user = new DBUser(name, options); listUser.put(name, user); } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "users") + ": " +e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "users") + ": " + e.getMessage()); + + } catch(Exception e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "users"); + throw new ExceptionDBGitRunTime(msg, e); } + return listUser; } @Override public Map getRoles() { - Map listRole = new HashMap(); - try { - List expressions = Arrays.asList( - "IF OBJECT_ID(N'GetRoleDDL', N'FN') IS NOT NULL DROP FUNCTION GetRoleDDL\n" + - "IF OBJECT_ID(N'GetRoleMembersDDL', N'FN') IS NOT NULL DROP FUNCTION GetRoleMembersDDL\n" - , - "CREATE FUNCTION dbo.GetRoleDDL(@roleName VARCHAR(255))\n" + - "RETURNS VARCHAR(MAX)\n" + - "BEGIN\n" + - " -- Script out the Role\n" + - " DECLARE @roleDesc VARCHAR(MAX)\n" + - " SET @roleDesc = 'CREATE ROLE [' + @roleName + '];'\n" + - " DECLARE @rolePerm VARCHAR(MAX)\n" + - " SET @rolePerm = ''\n" + - " SELECT @rolePerm = @rolePerm +\n" + - " CASE dp.state\n" + - " WHEN 'D' THEN 'DENY '\n" + - " WHEN 'G' THEN 'GRANT '\n" + - " WHEN 'R' THEN 'REVOKE '\n" + - " WHEN 'W' THEN 'GRANT '\n" + - " END + \n" + - " dp.permission_name + ' ' +\n" + - " CASE dp.class\n" + - " WHEN 0 THEN ''\n" + - " WHEN 1 THEN --table or column subset on the table\n" + - " CASE WHEN dp.major_id < 0 THEN\n" + - " + 'ON [sys].[' + OBJECT_NAME(dp.major_id) + '] '\n" + - " ELSE\n" + - " + 'ON [' +\n" + - " (SELECT SCHEMA_NAME(schema_id) + '].[' + name FROM sys.objects WHERE object_id = dp.major_id)\n" + - " + -- optionally concatenate column names\n" + - " CASE WHEN MAX(dp.minor_id) > 0 \n" + - " THEN '] ([' + REPLACE(\n" + - " (SELECT name + '], [' \n" + - " FROM sys.columns \n" + - " WHERE object_id = dp.major_id \n" + - " AND column_id IN (SELECT minor_id \n" + - " FROM sys.database_permissions \n" + - " WHERE major_id = dp.major_id\n" + - " AND USER_NAME(grantee_principal_id) IN (@roleName)\n" + - " )\n" + - " FOR XML PATH('')\n" + - " ) --replace final square bracket pair\n" + - " + '])', ', []', '')\n" + - " ELSE ']'\n" + - " END + ' '\n" + - " END\n" + - " WHEN 3 THEN 'ON SCHEMA::[' + SCHEMA_NAME(dp.major_id) + '] '\n" + - " WHEN 4 THEN 'ON ' + (SELECT RIGHT(type_desc, 4) + '::[' + name FROM sys.database_principals WHERE principal_id = dp.major_id) + '] '\n" + - " WHEN 5 THEN 'ON ASSEMBLY::[' + (SELECT name FROM sys.assemblies WHERE assembly_id = dp.major_id) + '] '\n" + - " WHEN 6 THEN 'ON TYPE::[' + (SELECT name FROM sys.types WHERE user_type_id = dp.major_id) + '] '\n" + - " WHEN 10 THEN 'ON XML SCHEMA COLLECTION::[' + (SELECT SCHEMA_NAME(schema_id) + '.' + name FROM sys.xml_schema_collections WHERE xml_collection_id = dp.major_id) + '] '\n" + - " WHEN 15 THEN 'ON MESSAGE TYPE::[' + (SELECT name FROM sys.service_message_types WHERE message_type_id = dp.major_id) + '] '\n" + - " WHEN 16 THEN 'ON CONTRACT::[' + (SELECT name FROM sys.service_contracts WHERE service_contract_id = dp.major_id) + '] '\n" + - " WHEN 17 THEN 'ON SERVICE::[' + (SELECT name FROM sys.services WHERE service_id = dp.major_id) + '] '\n" + - " WHEN 18 THEN 'ON REMOTE SERVICE BINDING::[' + (SELECT name FROM sys.remote_service_bindings WHERE remote_service_binding_id = dp.major_id) + '] '\n" + - " WHEN 19 THEN 'ON ROUTE::[' + (SELECT name FROM sys.routes WHERE route_id = dp.major_id) + '] '\n" + - " WHEN 23 THEN 'ON FULLTEXT CATALOG::[' + (SELECT name FROM sys.fulltext_catalogs WHERE fulltext_catalog_id = dp.major_id) + '] '\n" + - " WHEN 24 THEN 'ON SYMMETRIC KEY::[' + (SELECT name FROM sys.symmetric_keys WHERE symmetric_key_id = dp.major_id) + '] '\n" + - " WHEN 25 THEN 'ON CERTIFICATE::[' + (SELECT name FROM sys.certificates WHERE certificate_id = dp.major_id) + '] '\n" + - " WHEN 26 THEN 'ON ASYMMETRIC KEY::[' + (SELECT name FROM sys.asymmetric_keys WHERE asymmetric_key_id = dp.major_id) + '] '\n" + - " END COLLATE SQL_Latin1_General_CP1_CI_AS\n" + - " + 'TO [' + @roleName + ']' + \n" + - " CASE dp.state WHEN 'W' THEN ' WITH GRANT OPTION' ELSE '' END + ';'\n" + - " FROM sys.database_permissions dp\n" + - " WHERE USER_NAME(dp.grantee_principal_id) IN (@roleName)\n" + - " GROUP BY dp.state, dp.major_id, dp.permission_name, dp.class\n" + - " SELECT @roleDesc = @roleDesc + CASE WHEN @rolePerm IS NOT NULL THEN @rolePerm ELSE '' END\n" + - " RETURN @roleDesc\n" + - "END \n" - , - "CREATE FUNCTION dbo.GetRoleMembersDDL(@roleName VARCHAR(255))\n" + - "RETURNS VARCHAR(MAX)\n" + - "BEGIN\n" + - " -- Script out the Role\n" + - " DECLARE @roleDesc VARCHAR(MAX)\n" + - " SET @roleDesc = ''\n" + - " -- Display users within Role. Code stubbed by Joe Spivey\n" + - " SELECT @roleDesc = @roleDesc + 'EXECUTE sp_AddRoleMember ''' + roles.name + ''', ''' + users.name + ''';' \n" + - " FROM sys.database_principals users\n" + - " INNER JOIN sys.database_role_members link \n" + - " ON link.member_principal_id = users.principal_id\n" + - " INNER JOIN sys.database_principals roles \n" + - " ON roles.principal_id = link.role_principal_id\n" + - " WHERE roles.name = @roleName\n" + - " RETURN @roleDesc\n" + - "END \n" - ); + final Map listRole = new HashMap(); + final String usersQuery = + "SELECT \n" + + " dp.name roleName, dp.is_fixed_role isFixedRole,\n" + + " CASE WHEN dp.is_fixed_role = 0 AND dp.name != 'public' THEN dbo.GetRoleDDL(dp.name) ELSE '' " + + " END roleDDL,\n" + + " dbo.GetRoleMembersDDL(dp.name) membersDDL,\n" + + " CASE WHEN dp.is_fixed_role = 1 OR dp.name = 'public'" + + " THEN dbo.GetRoleMembersDDL(dp.name) " + + " ELSE dbo.GetRoleDDL(dp.name) + dbo.GetRoleMembersDDL(dp.name) " + + " END ddl\n" + + "FROM sys.database_principals dp\n" + + "WHERE dp.type = 'R'\n" + + "DROP FUNCTION GetRoleDDL\n" + + "DROP FUNCTION GetRoleMembersDDL"; + + List setupQueries = Arrays.asList( + "IF OBJECT_ID(N'GetRoleDDL', N'FN') IS NOT NULL DROP FUNCTION GetRoleDDL\n" + + "IF OBJECT_ID(N'GetRoleMembersDDL', N'FN') IS NOT NULL DROP FUNCTION GetRoleMembersDDL\n" + , + "CREATE FUNCTION dbo.GetRoleDDL(@roleName VARCHAR(255))\n" + + "RETURNS VARCHAR(MAX)\n" + + "BEGIN\n" + + " -- Script out the Role\n" + + " DECLARE @roleDesc VARCHAR(MAX)\n" + + " SET @roleDesc = 'CREATE ROLE [' + @roleName + '];'\n" + + " DECLARE @rolePerm VARCHAR(MAX)\n" + + " SET @rolePerm = ''\n" + + " SELECT @rolePerm = @rolePerm +\n" + + " CASE dp.state\n" + + " WHEN 'D' THEN 'DENY '\n" + + " WHEN 'G' THEN 'GRANT '\n" + + " WHEN 'R' THEN 'REVOKE '\n" + + " WHEN 'W' THEN 'GRANT '\n" + + " END + \n" + + " dp.permission_name + ' ' +\n" + + " CASE dp.class\n" + + " WHEN 0 THEN ''\n" + + " WHEN 1 THEN --table or column subset on the table\n" + + " CASE WHEN dp.major_id < 0 THEN\n" + + " + 'ON [sys].[' + OBJECT_NAME(dp.major_id) + '] '\n" + + " ELSE\n" + + " + 'ON [' +\n" + + " (SELECT SCHEMA_NAME(schema_id) + '].[' + name FROM sys.objects WHERE object_id = dp.major_id)\n" + + " + -- optionally concatenate column names\n" + + " CASE WHEN MAX(dp.minor_id) > 0 \n" + + " THEN '] ([' + REPLACE(\n" + + " (SELECT name + '], [' \n" + + " FROM sys.columns \n" + + " WHERE object_id = dp.major_id \n" + + " AND column_id IN (SELECT minor_id \n" + + " FROM sys.database_permissions \n" + + " WHERE major_id = dp.major_id\n" + + " AND USER_NAME(grantee_principal_id) IN (@roleName)\n" + + " )\n" + + " FOR XML PATH('')\n" + + " ) --replace final square bracket pair\n" + + " + '])', ', []', '')\n" + + " ELSE ']'\n" + + " END + ' '\n" + + " END\n" + + " WHEN 3 THEN 'ON SCHEMA::[' + SCHEMA_NAME(dp.major_id) + '] '\n" + + " WHEN 4 THEN 'ON ' + (SELECT RIGHT(type_desc, 4) + '::[' + name FROM sys.database_principals WHERE principal_id = dp.major_id) + '] '\n" + + " WHEN 5 THEN 'ON ASSEMBLY::[' + (SELECT name FROM sys.assemblies WHERE assembly_id = dp.major_id) + '] '\n" + + " WHEN 6 THEN 'ON TYPE::[' + (SELECT name FROM sys.types WHERE user_type_id = dp.major_id) + '] '\n" + + " WHEN 10 THEN 'ON XML SCHEMA COLLECTION::[' + (SELECT SCHEMA_NAME(schema_id) + '.' + name FROM sys.xml_schema_collections WHERE xml_collection_id = dp.major_id) + '] '\n" + + " WHEN 15 THEN 'ON MESSAGE TYPE::[' + (SELECT name FROM sys.service_message_types WHERE message_type_id = dp.major_id) + '] '\n" + + " WHEN 16 THEN 'ON CONTRACT::[' + (SELECT name FROM sys.service_contracts WHERE service_contract_id = dp.major_id) + '] '\n" + + " WHEN 17 THEN 'ON SERVICE::[' + (SELECT name FROM sys.services WHERE service_id = dp.major_id) + '] '\n" + + " WHEN 18 THEN 'ON REMOTE SERVICE BINDING::[' + (SELECT name FROM sys.remote_service_bindings WHERE remote_service_binding_id = dp.major_id) + '] '\n" + + " WHEN 19 THEN 'ON ROUTE::[' + (SELECT name FROM sys.routes WHERE route_id = dp.major_id) + '] '\n" + + " WHEN 23 THEN 'ON FULLTEXT CATALOG::[' + (SELECT name FROM sys.fulltext_catalogs WHERE fulltext_catalog_id = dp.major_id) + '] '\n" + + " WHEN 24 THEN 'ON SYMMETRIC KEY::[' + (SELECT name FROM sys.symmetric_keys WHERE symmetric_key_id = dp.major_id) + '] '\n" + + " WHEN 25 THEN 'ON CERTIFICATE::[' + (SELECT name FROM sys.certificates WHERE certificate_id = dp.major_id) + '] '\n" + + " WHEN 26 THEN 'ON ASYMMETRIC KEY::[' + (SELECT name FROM sys.asymmetric_keys WHERE asymmetric_key_id = dp.major_id) + '] '\n" + + " END COLLATE SQL_Latin1_General_CP1_CI_AS\n" + + " + 'TO [' + @roleName + ']' + \n" + + " CASE dp.state WHEN 'W' THEN ' WITH GRANT OPTION' ELSE '' END + ';'\n" + + " FROM sys.database_permissions dp\n" + + " WHERE USER_NAME(dp.grantee_principal_id) IN (@roleName)\n" + + " GROUP BY dp.state, dp.major_id, dp.permission_name, dp.class\n" + + " SELECT @roleDesc = @roleDesc + CASE WHEN @rolePerm IS NOT NULL THEN @rolePerm ELSE '' END\n" + + " RETURN @roleDesc\n" + + "END \n" + , + "CREATE FUNCTION dbo.GetRoleMembersDDL(@roleName VARCHAR(255))\n" + + "RETURNS VARCHAR(MAX)\n" + + "BEGIN\n" + + " -- Script out the Role\n" + + " DECLARE @roleDesc VARCHAR(MAX)\n" + + " SET @roleDesc = ''\n" + + " -- Display users within Role. Code stubbed by Joe Spivey\n" + + " SELECT @roleDesc = @roleDesc + 'EXECUTE sp_AddRoleMember ''' + roles.name + ''', ''' + users.name + ''';' \n" + + " FROM sys.database_principals users\n" + + " INNER JOIN sys.database_role_members link \n" + + " ON link.member_principal_id = users.principal_id\n" + + " INNER JOIN sys.database_principals roles \n" + + " ON roles.principal_id = link.role_principal_id\n" + + " WHERE roles.name = @roleName\n" + + " RETURN @roleDesc\n" + + "END \n" + ); + + try (Statement stmt = getConnection().createStatement();) { - String query = - "SELECT \n" + - " dp.name roleName, dp.is_fixed_role isFixedRole,\n" + - " CASE WHEN dp.is_fixed_role = 0 AND dp.name != 'public' THEN dbo.GetRoleDDL(dp.name) ELSE '' " + - " END roleDDL,\n" + - " dbo.GetRoleMembersDDL(dp.name) membersDDL,\n" + - " CASE WHEN dp.is_fixed_role = 1 OR dp.name = 'public'" + - " THEN dbo.GetRoleMembersDDL(dp.name) " + - " ELSE dbo.GetRoleDDL(dp.name) + dbo.GetRoleMembersDDL(dp.name) " + - " END ddl\n" + - "FROM sys.database_principals dp\n" + - "WHERE dp.type = 'R'\n" + - "DROP FUNCTION GetRoleDDL\n" + - "DROP FUNCTION GetRoleMembersDDL"; - - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - - for(String expr : expressions){ + for(String expr : setupQueries){ stmt.execute(expr); } - ResultSet rs = stmt.executeQuery(query); - while(rs.next()){ - String name = rs.getString("rolename"); - DBRole role = new DBRole(name); - rowToProperties(rs, role.getOptions()); - listRole.put(name, role); + try(ResultSet rs = stmt.executeQuery(usersQuery);){ + while(rs.next()){ + final String name = rs.getString("rolename"); + final StringProperties options = new StringProperties(rs); + + DBRole role = new DBRole(name, options); + listRole.put(name, role); + } } - stmt.close(); + }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "roles") + ": " + e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "roles") + ": " + e.getMessage()); + final DBGitLang msg = lang.getValue("errors", "adapter", "roles"); + throw new ExceptionDBGitRunTime(msg, e); } 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/mssql/DBBackupAdapterMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBBackupAdapterMssql.java index 102a891..27e5ee0 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBBackupAdapterMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBBackupAdapterMssql.java @@ -43,7 +43,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio createSchema(stLog, schema); } - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); ddl = ddl.replace(schema + "." + objectName, getFullDbName(schema, objectName)); @@ -53,7 +53,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio if (file.exists()) obj = metaSql.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else if (obj instanceof MetaTable) { @@ -77,7 +77,7 @@ else if (obj instanceof MetaTable) { createSchema(stLog, schema); } - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); dropIfExists(isSaveToSchema() ? PREFIX + schema : schema, isSaveToSchema() ? objectName : PREFIX + objectName, stLog); @@ -123,7 +123,7 @@ else if (obj instanceof MetaTable) { File file = new File(DBGitPath.getFullPath() + metaTable.getFileName()); if (file.exists()) obj = metaTable.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else if (obj instanceof MetaSequence) { MetaSequence metaSequence = (MetaSequence) obj; @@ -138,7 +138,7 @@ else if (obj instanceof MetaSequence) { String sequenceName = getFullDbName(schema, objectName); - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); StringProperties props = metaSequence.getSequence().getOptions(); String seqName = props.get("name").getData(); @@ -178,17 +178,16 @@ else if (obj instanceof MetaSequence) { File file = new File(DBGitPath.getFullPath() + metaSequence.getFileName()); if (file.exists()) obj = metaSequence.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } } catch (SQLException e1) { throw new ExceptionDBGitRestore( lang.getValue("errors", "restore", "objectRestoreError") .withParams(obj.getName() + ": " + e1.getLocalizedMessage()) + , e1 ); } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - connection.rollback(); throw new ExceptionDBGit(lang.getValue("errors", "backup", "backupError").withParams(obj.getName()), e); } finally { stLog.close(); @@ -285,12 +284,12 @@ public boolean isExists(String owner, String objectName) throws SQLException { public boolean createSchema(StatementLogging stLog, String schema) { try { if (!adapter.getSchemes().containsKey(schema)) { - ConsoleWriter.detailsPrintLn(lang.getValue("general", "backup", "creatingSchema").withParams(PREFIX + schema)); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "creatingSchema").withParams(PREFIX + schema), messageLevel); stLog.execute(MessageFormat.format("CREATE SCHEMA {0}{1}", PREFIX, schema)); } return true; } catch (SQLException e) { - ConsoleWriter.println(lang.getValue("errors", "backup", "cannotCreateSchema").withParams(e.getLocalizedMessage())); + ConsoleWriter.println(lang.getValue("errors", "backup", "cannotCreateSchema").withParams(e.getLocalizedMessage()), messageLevel); return false; } } diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreFunctionMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreFunctionMssql.java index 79bbd94..3bde897 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreFunctionMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreFunctionMssql.java @@ -21,7 +21,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreFnc").withParams(obj.getName()), 1); try { if (obj instanceof MetaFunction) { MetaFunction restoreFunction = (MetaFunction)obj; @@ -53,14 +52,15 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "function", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreProcedureMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreProcedureMssql.java index 8e9c6f9..5e50e36 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreProcedureMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreProcedureMssql.java @@ -21,7 +21,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restorePrc").withParams(obj.getName()), 1); try { if (obj instanceof MetaProcedure) { MetaProcedure restoreProcedure = (MetaProcedure)obj; @@ -42,17 +41,18 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { st.execute(restoreProcedure.getSqlObject().getSql(), "/"); //TODO Восстановление привилегий } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "procedure", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreRoleMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreRoleMssql.java index 8abc027..e8be46f 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreRoleMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreRoleMssql.java @@ -21,7 +21,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreRole").withParams(obj.getName()), 1); try { if (obj instanceof MetaRole) { MetaRole restoreRole = (MetaRole)obj; @@ -60,14 +59,16 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { connect.commit(); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "role", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); + ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail"), 0); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreSchemaMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreSchemaMssql.java index 65994b6..356e63e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreSchemaMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreSchemaMssql.java @@ -2,6 +2,7 @@ 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.DBSchema; import ru.fusionsoft.dbgit.meta.IMetaObject; @@ -19,7 +20,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreSchema").withParams(obj.getName()), 1); try { if (obj instanceof MetaSchema) { MetaSchema restoreSchema = (MetaSchema)obj; @@ -30,13 +30,13 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { if(restoreSchema.getObjectOption().getName().equals(sch.getName())){ exist = true; // TODO MSSQL restore Schema script - //String test1 = changedsch.getObjectOption().getName(); - //String test2 = changedsch.getObjectOption().getOptions().getChildren().get("usename").getData(); - if(!restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData().equals(sch.getOptions().getChildren().get("usename").getData())) { + + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + if(!restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData().equals(sch.getOptions().getChildren().get("usename").getData())) { st.execute("ALTER SCHEMA "+ restoreSchema.getObjectOption().getName() +" OWNER TO "+ restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData()); + } } - //TODO Восстановление привилегий } } } @@ -49,14 +49,15 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "schema", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreSequenceMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreSequenceMssql.java index 6c5fde3..5b48f14 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreSequenceMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreSequenceMssql.java @@ -22,7 +22,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreSeq").withParams(obj.getName()), 1); try { if (obj instanceof MetaSequence) { @@ -80,14 +79,15 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "sequence", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableDataMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableDataMssql.java index a3c5aec..cd0e06a 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableDataMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableDataMssql.java @@ -61,7 +61,7 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { if (getAdapter().getTable(schema, currentTableData.getTable().getName()) != null) { currentTableData.setDataTable(getAdapter().getTableData(schema, currentTableData.getTable().getName())); - ResultSet rs = currentTableData.getDataTable().getResultSet(); + ResultSet rs = currentTableData.getDataTable().resultSet(); TreeMapRowData mapRows = new TreeMapRowData(); @@ -93,14 +93,17 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - //TODO WTF???? - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - //return true; + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table data cached", obj.getType().getValue() + )); } } - else - { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + else { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table data", obj.getType().getValue() + )); } } @@ -121,7 +124,6 @@ public void restoreTableDataMssql(MetaTableData restoreTableData, MetaTableData schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); String tblName = schema + "." + restoreTableData.getTable().getName(); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "tableData").withParams(tblName) + "\n", 1); // TODO MSSQL restore TableData script ResultSet rsTypes = st.executeQuery("select column_name, data_type from information_schema.columns \r\n" + @@ -135,7 +137,7 @@ public void restoreTableDataMssql(MetaTableData restoreTableData, MetaTableData if(!diffTableData.entriesOnlyOnLeft().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "inserting"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "inserting"), messageLevel); for(RowData rowData:diffTableData.entriesOnlyOnLeft().values()) { ArrayList fieldsList = new ArrayList(rowData.getData().keySet()); @@ -143,14 +145,14 @@ public void restoreTableDataMssql(MetaTableData restoreTableData, MetaTableData String insertQuery = "insert into "+tblName + fields+valuesToString(rowData.getData().values(), colTypes, fieldsList) + ";\n"; - ConsoleWriter.detailsPrintLn(insertQuery); + ConsoleWriter.detailsPrintln(insertQuery, messageLevel+1); PrepareStatementLogging ps = new PrepareStatementLogging(connect, insertQuery, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); int i = 0; for (ICellData data : rowData.getData().values()) { i++; - ConsoleWriter.detailsPrintLn(data.getSQLData()); + ConsoleWriter.detailsPrintln(data.getSQLData(), messageLevel+1); ResultSet rs = st.executeQuery("select data_type from information_schema.columns \r\n" + "where lower(table_schema||'.'||table_name) = lower('" + tblName + "') and lower(column_name) = '" + fieldsList.get(i - 1) + "'"); @@ -171,11 +173,11 @@ public void restoreTableDataMssql(MetaTableData restoreTableData, MetaTableData st.execute(insertQuery); } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } if(!diffTableData.entriesOnlyOnRight().isEmpty()){ - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "deleting"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "deleting"), messageLevel); String deleteQuery=""; Map primarykeys = new HashMap(); for(RowData rowData:diffTableData.entriesOnlyOnRight().values()) { @@ -213,11 +215,11 @@ public void restoreTableDataMssql(MetaTableData restoreTableData, MetaTableData if(deleteQuery.length()>1) { st.execute(deleteQuery); } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } if(!diffTableData.entriesDiffering().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "updating"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "updating"), messageLevel); String updateQuery=""; Map primarykeys = new HashMap(); for(ValueDifference diffRowData:diffTableData.entriesDiffering().values()) { @@ -266,15 +268,15 @@ public void restoreTableDataMssql(MetaTableData restoreTableData, MetaTableData updateQuery="update "+tblName+ " set "+updFields + " = " + valuesToString(tempCols.values(), colTypes, fieldsList) + " where " + keyFields+ "=" +keyValues+";\n"; - ConsoleWriter.detailsPrintLn(updateQuery); + ConsoleWriter.detailsPrintln(updateQuery, messageLevel+1); PrepareStatementLogging ps = new PrepareStatementLogging(connect, updateQuery, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); int i = 0; - ConsoleWriter.detailsPrintLn("vals for " + keyValues + ":" + diffRowData.leftValue().getData().values()); + ConsoleWriter.detailsPrintln("vals for " + keyValues + ":" + diffRowData.leftValue().getData().values(), messageLevel); for (ICellData data : diffRowData.leftValue().getData().values()) { i++; - ConsoleWriter.detailsPrintLn(data.getSQLData()); + ConsoleWriter.detailsPrintln(data.getSQLData(), messageLevel+1); ResultSet rs = st.executeQuery("select data_type from information_schema.columns \r\n" + "where lower(table_schema||'.'||table_name) = lower('" + tblName + "') and lower(column_name) = '" + fieldsList.get(i - 1) + "'"); @@ -305,15 +307,14 @@ public void restoreTableDataMssql(MetaTableData restoreTableData, MetaTableData } } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); if(updateQuery.length()>1) { - ConsoleWriter.println(updateQuery); + ConsoleWriter.println(updateQuery, messageLevel+1); st.execute(updateQuery); } } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(restoreTableData.getTable().getSchema() + "." + restoreTableData.getTable().getName()), e); } finally { st.close(); @@ -447,7 +448,7 @@ public String keysToString(Set keys) { } public void restoreTableConstraintMssql(MetaTable table) throws Exception { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreConstr").withParams(table.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreConstr").withParams(table.getName()), messageLevel); IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); @@ -460,11 +461,9 @@ public void restoreTableConstraintMssql(MetaTable table) throws Exception { } } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(schema + "." + table.getTable().getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } } @@ -477,7 +476,7 @@ public void removeTableConstraintsMssql(MetaTable table) throws Exception { String schema = getPhisicalSchema(table.getTable().getSchema()); schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); String tblName = schema + "." +table.getTable().getName(); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "delConstr").withParams(table.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "delConstr").withParams(table.getName()), messageLevel); try { //TODO MSSQL remove table constraints script ResultSet rs = stCnt.executeQuery("SELECT *\r\n" + @@ -506,11 +505,9 @@ public void removeTableConstraintsMssql(MetaTable table) throws Exception { } } //} - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "cannotRestore").withParams(schema + "." + table.getTable().getName()), e); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableMssql.java index d4852e8..d54f619 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableMssql.java @@ -1,10 +1,11 @@ package ru.fusionsoft.dbgit.mssql; -import ch.qos.logback.classic.db.names.TableName; +import com.diogonunes.jcdp.color.api.Ansi; import com.google.common.collect.Lists; import com.google.common.collect.MapDifference; import com.google.common.collect.MapDifference.ValueDifference; import com.google.common.collect.Maps; +import java.util.regex.Pattern; import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; import ru.fusionsoft.dbgit.adapters.IDBAdapter; import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; @@ -53,14 +54,10 @@ public void restoreTableMssql(IMetaObject obj) throws Exception { MetaTable restoreTable = (MetaTable) obj; String tblSchema = getPhisicalSchema(restoreTable.getTable().getSchema().toLowerCase()); String tblName = restoreTable.getTable().getName(); - String tblSam = tblSchema+"."+tblName; - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTable").withParams(tblSam) + "\n", 1); - - Map tables = adapter.getTables(tblSchema); if(!isTablePresent(tblSchema ,tblName)){ - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "createTable"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "createTable"), messageLevel); DBTable table = restoreTable.getTable(); @@ -72,7 +69,7 @@ public void restoreTableMssql(IMetaObject obj) throws Exception { ")"; st.execute(ddl); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } restoreTableFieldsMssql(restoreTable, tblName, tblSchema, st); @@ -87,12 +84,13 @@ public void restoreTableMssql(IMetaObject obj) throws Exception { restoreTablePksMssql(restoreTable, st); } } - else - { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + else { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); @@ -103,7 +101,7 @@ public void restoreTableIndexesMssql(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreIndex").withParams(obj.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreIndex").withParams(obj.getName()), messageLevel); try { if (obj instanceof MetaTable) { MetaTable restoreTable = (MetaTable)obj; @@ -168,21 +166,17 @@ public void restoreTableIndexesMssql(IMetaObject obj) throws Exception { st.execute(ind.getSql()); }*/ String errText = lang.getValue("errors", "meta", "notFound").withParams(obj.getName()); - ConsoleWriter.detailsPrintlnRed(errText); throw new ExceptionDBGitRestore(errText); } } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } } @@ -191,7 +185,7 @@ private void restoreTableConstraintMssql(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreConstr").withParams(obj.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreConstr").withParams(obj.getName()), messageLevel); try { if (obj instanceof MetaTable) { MetaTable restoreTable = (MetaTable)obj; @@ -214,15 +208,15 @@ private void restoreTableConstraintMssql(IMetaObject obj) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } } @@ -246,7 +240,6 @@ public void removeMetaObject(IMetaObject obj) throws Exception { ); } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); } finally { st.close(); @@ -276,7 +269,7 @@ private void restoreTableFieldsMssql(MetaTable restoreTable, String tblName, Str if( !restoringUniqueFields.isEmpty()){ - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "addColumns"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "addColumns"), messageLevel); List values = restoringUniqueFields.values() .stream() @@ -288,22 +281,22 @@ private void restoreTableFieldsMssql(MetaTable restoreTable, String tblName, Str st.execute(fieldDdl); } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } if( !existingUniqueFields.isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "droppingColumns"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "droppingColumns"), messageLevel); for(DBTableField tblField:existingUniqueFields.values()) { String fieldDdl = MessageFormat.format("ALTER TABLE {1} DROP COLUMN [{2}]", tblSam, tblField.getName()); st.execute(fieldDdl); } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } if(!mergingFields.isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "modifyColumns"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "modifyColumns"), messageLevel); for(ValueDifference fld : mergingFields.values()) { DBTableField oldValue = fld.rightValue(); @@ -323,7 +316,7 @@ private void restoreTableFieldsMssql(MetaTable restoreTable, String tblName, Str } } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } } @@ -350,10 +343,12 @@ private void removeTableConstraintsMssql(IMetaObject obj) throws Exception { } else { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } } @@ -364,7 +359,7 @@ private boolean getIsPk(DBConstraint dbConstraint){ } private void restoreTablePksMssql(MetaTable restoreTable, StatementLogging st) throws SQLException { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "addPk"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "addPk"), messageLevel); String tblSchema = restoreTable.getTable().getSchema(); String tblName = restoreTable.getTable().getName(); boolean flagPkCreated = false; @@ -374,7 +369,6 @@ private void restoreTablePksMssql(MetaTable restoreTable, StatementLogging st) t if(pkConstraints.size() > 1) throw new SQLException(); for(DBConstraint pk : pkConstraints){ - String ddl = pk.getSql(); ddl = ddl.replaceFirst("ALTER TABLE\\s+\\[?\\w+\\]?.\\[?\\w+\\]?\\s+ADD\\s+CONSTRAINT\\s+\\[?\\w+\\]?\\s+", ""); ddl = MessageFormat.format( @@ -387,13 +381,13 @@ private void restoreTablePksMssql(MetaTable restoreTable, StatementLogging st) t } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); flagPkCreated = true; if (!flagPkCreated) { for(DBTableField field: restoreTable.getFields().values()) { if (field.getIsPrimaryKey()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "addPk"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "addPk"), messageLevel); String ddl = MessageFormat.format( "ALTER TABLE {0} ADD CONSTRAINT PK_{1}_{2} PRIMARY KEY([{2}])", @@ -401,7 +395,7 @@ private void restoreTablePksMssql(MetaTable restoreTable, StatementLogging st) t ); st.execute(ddl); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); break; + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); break; } } } diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableSpaceMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableSpaceMssql.java index 09349c5..4ac2efc 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableSpaceMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTableSpaceMssql.java @@ -2,6 +2,7 @@ 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.DBTableSpace; import ru.fusionsoft.dbgit.meta.IMetaObject; @@ -19,7 +20,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTableSpace").withParams(obj.getName()), 1); try { if (obj instanceof MetaTableSpace) { MetaTableSpace restoreTableSpace = (MetaTableSpace)obj; @@ -41,10 +41,12 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { String currentowner = tblspace.getOptions().getChildren().get("usename").getData(); String currentloc = tblspace.getOptions().getChildren().get("pg_tablespace_location").getData(); - if(!restoreowner.equals(currentowner)) { - st.execute("alter tablespace "+ restorename +" owner to "+ restoreowner); - } + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + if(!restoreowner.equals(currentowner)) { + st.execute("alter tablespace "+ restorename +" owner to "+ restoreowner); + } + } if(restoreTableSpace.getObjectOption().getOptions().getChildren().containsKey("spcoptions")) { String options = restoreTableSpace.getObjectOption().getOptions().getChildren().get("spcoptions").getData().replaceAll("[\\{\\}]", ""); st.execute("alter tablespace "+ restorename +" set ("+ options+")"); @@ -68,14 +70,18 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "tablespace", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError") + .withParams(obj.getName()) + , e + ); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTriggerMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTriggerMssql.java index cc2c589..dcd0a3e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTriggerMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreTriggerMssql.java @@ -24,7 +24,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTrigger").withParams(obj.getName()), 1); try { if (obj instanceof MetaTrigger) { MetaTrigger restoreTrigger = (MetaTrigger)obj; @@ -56,22 +55,23 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { if(!ddl.isEmpty()){ st.execute(ddl); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "encrypted").withParams(triggerName)); + ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "encrypted").withParams(triggerName), messageLevel); } } } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "trigger", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreUserMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreUserMssql.java index ff16155..d757fa3 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreUserMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreUserMssql.java @@ -20,7 +20,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreUser").withParams(obj.getName()), 1); try { if (obj instanceof MetaUser) { MetaUser usr = (MetaUser)obj; @@ -60,14 +59,15 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "user", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreViewMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreViewMssql.java index 4b7d8e6..86da9c0 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreViewMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/DBRestoreViewMssql.java @@ -2,6 +2,7 @@ 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.DBView; import ru.fusionsoft.dbgit.meta.IMetaObject; @@ -19,7 +20,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreView").withParams(obj.getName()), 1); try { if (obj instanceof MetaView) { MetaView restoreView = (MetaView)obj; @@ -47,21 +47,26 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { if (!query.endsWith(";")) query = query + ";"; query = query + "\n"; - query+= "ALTER VIEW "+restoreView.getSqlObject().getName() +" OWNER TO "+restoreView.getSqlObject().getOwner()+";\n"; + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + query+= "ALTER VIEW "+restoreView.getSqlObject().getName() +" OWNER TO \""+restoreView.getSqlObject().getOwner()+"\";\n"; + } + st.execute(query); + //TODO Восстановление привилегий } } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "view", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/FactoryDBAdapterRestoreMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/FactoryDBAdapterRestoreMssql.java index 2fd0405..c80150e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/FactoryDBAdapterRestoreMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/FactoryDBAdapterRestoreMssql.java @@ -41,7 +41,7 @@ public class FactoryDBAdapterRestoreMssql implements IFactoryDBAdapterRestoteMet public IDBAdapterRestoreMetaData getAdapterRestore(IDBGitMetaType tp, IDBAdapter adapter) { if (!restoreAdapters.containsKey(tp.getValue())) { //return new DBRestoreMetaNotSupport(); - ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "restore", "cannotRestore").withParams(tp.getValue())); + ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "restore", "cannotRestore").withParams(tp.getValue()), messageLevel); return null; } diff --git a/src/main/java/ru/fusionsoft/dbgit/mssql/FactoryDbConvertAdapterMssql.java b/src/main/java/ru/fusionsoft/dbgit/mssql/FactoryDbConvertAdapterMssql.java index 4d6748d..d20e7b3 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mssql/FactoryDbConvertAdapterMssql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mssql/FactoryDbConvertAdapterMssql.java @@ -2,6 +2,7 @@ import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.meta.DBGitMetaType; import ru.fusionsoft.dbgit.mssql.converters.TableConverterMssql; import ru.fusionsoft.dbgit.mssql.converters.TableDataConverterMssql; @@ -26,7 +27,11 @@ public class FactoryDbConvertAdapterMssql implements IFactoryDBConvertAdapter { @Override public IDBConvertAdapter getConvertAdapter(String objectType) throws Exception { if (!converters.containsKey(objectType)) { - ConsoleWriter.println("Cannot convert " + objectType + "!"); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("errors", "convert", "cannotConvert") + .withParams(objectType) + , 1 + ); return null; } else return converters.get(objectType); diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/DBAdapterMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/DBAdapterMySql.java index b110e44..563da91 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/DBAdapterMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/DBAdapterMySql.java @@ -7,12 +7,11 @@ import java.sql.SQLException; import java.sql.Statement; import java.text.MessageFormat; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.TimeUnit; +import com.google.common.collect.ImmutableMap; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import com.axiomalaska.jdbc.NamedParameterPreparedStatement; @@ -21,18 +20,12 @@ import ru.fusionsoft.dbgit.adapters.IFactoryDBAdapterRestoteMetaData; import ru.fusionsoft.dbgit.adapters.IFactoryDBBackupAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; -import ru.fusionsoft.dbgit.core.DBGitConfig; -import ru.fusionsoft.dbgit.core.DBGitLang; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; +import ru.fusionsoft.dbgit.core.*; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.core.db.FieldType; -import ru.fusionsoft.dbgit.data_table.DateData; -import ru.fusionsoft.dbgit.data_table.FactoryCellData; -import ru.fusionsoft.dbgit.data_table.LongData; -import ru.fusionsoft.dbgit.data_table.MapFileData; -import ru.fusionsoft.dbgit.data_table.StringData; 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; @@ -46,8 +39,10 @@ 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; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.LoggerUtil; @@ -59,9 +54,9 @@ public class DBAdapterMySql extends DBAdapter { private FactoryDBRestoreAdapterMySql restoreFactory = new FactoryDBRestoreAdapterMySql(); private FactoryDBConvertAdapterMySql convertFactory = new FactoryDBConvertAdapterMySql(); private FactoryDBBackupAdapterMySql backupFactory = new FactoryDBBackupAdapterMySql(); - public static Set reservedWords; + public final static Set reservedWords = new HashSet<>(); - public static Object escapeNameIfNeeded(String name) { + public String escapeNameIfNeeded(String name) { boolean shouldBeEscaped = false; //TODO Permitted characters in unquoted identifiers: //ASCII: [0-9,a-z,A-Z$_] (basic Latin letters, digits 0-9, dollar, underscore) @@ -81,43 +76,119 @@ public static Object escapeNameIfNeeded(String name) { public IFactoryDBAdapterRestoteMetaData getFactoryRestore() { return restoreFactory; } + @Override + public IFactoryDBConvertAdapter getConvertAdapterFactory() { + return convertFactory; + } + @Override + public IFactoryDBBackupAdapter getBackupAdapterFactory() { + return backupFactory; + } @Override - public void startUpdateDB() { + public boolean userHasRightsToGetDdlOfOtherUsers() { + return true; + } + + @Override + public DbType getDbType() { + return DbType.MYSQL; + } + @Override + public String getDbVersion() { + try ( + PreparedStatement stmt = getConnection().prepareStatement("SELECT version()"); + ResultSet resultSet = stmt.executeQuery(); + ) { + if(!resultSet.next()) throw new ExceptionDBGitRunTime("failed to get db version resultset"); + final String result = resultSet.getString(1); + + return result; + } catch (SQLException e) { + throw new ExceptionDBGitRunTime("failed to get db version resultset"); + } + } + @Override + public String getDefaultScheme() { + try { + return getConnection().getCatalog(); + } catch (SQLException e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "getSchema"); + throw new ExceptionDBGitRunTime(msg); + } + } + + @Override + public void createSchemaIfNeed(String schemaName) throws ExceptionDBGit { + final String query = + "select count(*) cnt " + + "from information_schema.schemata " + + "where upper(schema_name) = '" + schemaName.toUpperCase() + "'"; + + try ( + Statement st = connect.createStatement(); + ResultSet rs = st.executeQuery(query); + ) { + + if(!rs.next()) throw new ExceptionDBGitRunTime("failed to get schemas count resultset"); + + if (rs.getInt("cnt") == 0){ + try(StatementLogging stLog = new StatementLogging(connect, getStreamOutputSqlCommand(), isExecSql());) { + stLog.execute("create schema " + schemaName); + } + } + + } catch (SQLException e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "createSchema"); + throw new ExceptionDBGit(msg); + } + } + @Override + public void createRoleIfNeed(String roleName) throws ExceptionDBGit { // TODO Auto-generated method stub } + @Override + public boolean isReservedWord(String word) { + return reservedWords.contains(word.toUpperCase()); + } + + @Override + public void startUpdateDB() { + // TODO Auto-generated method stub + } @Override public void endUpdateDB() { // TODO Auto-generated method stub - } @Override public IMapMetaObject loadCustomMetaObjects() { - return null; + return new TreeMapMetaObject(Collections.emptyList()); } @Override public Map getSchemes() { - Map listScheme = new HashMap(); - try { - String query = "select schema_name\r\n" + - "from information_schema.schemata"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + final Map listScheme = new HashMap(); + final String query = + "select schema_name\r\n" + + "from information_schema.schemata"; + + try ( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ){ + while(rs.next()){ - String name = rs.getString("schema_name"); - DBSchema scheme = new DBSchema(name); - rowToProperties(rs, scheme.getOptions()); - listScheme.put(name, scheme); - } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "schemes").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "schemes").toString(), e); + final String name = rs.getString("schema_name"); + final DBSchema scheme = new DBSchema(name, new StringProperties(rs)); + listScheme.put(name, scheme); + } + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "schemes").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listScheme; @@ -125,633 +196,691 @@ public Map getSchemes() { @Override public Map getTableSpaces() { - // TODO Auto-generated method stub - return null; + return Collections.emptyMap(); } @Override public Map getSequences(String schema) { - Map sequences = new HashMap(); - try { - String query = "select column_name, table_name, column_type, extra from information_schema.columns" + - " where extra like '%auto_increment%' and table_schema='" + schema + "'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + final Map sequences = new HashMap<>(); + final String query = + " select column_name, table_name, column_type, extra " + + " from information_schema.columns" + + " where extra like '%auto_increment%' and table_schema='" + schema + "'"; + + try( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ) { + while(rs.next()) { - String name = rs.getString("column_name"); - DBSequence seq = new DBSequence(name); - Statement stmtValue = connect.createStatement(); - ResultSet rsValue = stmtValue.executeQuery("select coalesce(max(" + rs.getString("column_name") + "), 0) as nextval" + - " from " + schema + ".`" + rs.getString("table_name") + "`"); - rsValue.next(); - seq.setSchema(schema); - seq.setValue(rsValue.getLong("nextval")); - sequences.put(name, seq); - stmtValue.close(); + + final String valueQuery = + " select coalesce(max(" + rs.getString("column_name") + "), 0) as nextval" + + " from " + schema + ".`" + rs.getString("table_name") + "`"; + + try(Statement stmtValue = getConnection().createStatement(); ResultSet rsValue = stmtValue.executeQuery(valueQuery)){ + if(rsValue.next()){ + final String name = rs.getString("column_name"); + final String owner = ""; + final Long value = rsValue.getLong("nextval"); + final DBSequence seq = new DBSequence(name, new StringProperties(rs), schema, owner, Collections.emptySet(), value); + sequences.put(name, seq); + } + } + } - stmt.close(); } catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "seq").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "seq").toString(), e); + final String msg = lang.getValue("errors", "adapter", "seq").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return sequences; } @Override public DBSequence getSequence(String schema, String name) { - DBSequence seq = null; - try { - String query = "select column_name, table_name, column_type, extra from information_schema.columns" + - " where extra like '%auto_increment%' and table_schema='" + schema + "' and column_name='" + name + "'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + final String query = + "select column_name, table_name, column_type, extra from information_schema.columns" + + " where extra like '%auto_increment%' and table_schema='" + schema + "' and column_name='" + name + "'"; + + try ( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ){ + if(rs.next()) { - seq = new DBSequence(name); - Statement stmtValue = connect.createStatement(); - ResultSet rsValue = stmtValue.executeQuery("select coalesce(max(" + rs.getString("column_name") + "), 0) as nextval" + - " from " + schema + ".`" + rs.getString("table_name") + "`"); - rsValue.next(); - seq.setSchema(schema); - seq.setValue(rsValue.getLong("nextval")); - stmtValue.close(); + final String valueQuery = + "select coalesce(max(" + rs.getString("column_name") + "), 0) as nextval" + + " from " + schema + ".`" + rs.getString("table_name") + "`"; + + try( + Statement stmtValue = connect.createStatement(); + ResultSet rsValue = stmtValue.executeQuery(valueQuery) + ){ + if(!rsValue.next()) throw new ExceptionDBGitRunTime("failed to get seq value resultset"); + + final String nameSeq = rs.getString("column_name"); + final String ownerSeq = ""; + final Long valueSeq = rsValue.getLong("nextval"); + + return new DBSequence(nameSeq, new StringProperties(rs), schema, ownerSeq, Collections.emptySet(), valueSeq); + } + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - stmt.close(); + } catch (Exception e) { - logger.error(lang.getValue("errors", "adapter", "seq").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "seq").toString(), e); + final String msg = lang.getValue("errors", "adapter", "seq").toString(); + throw new ExceptionDBGitRunTime(msg, e); } - return seq; + } @Override public Map getTables(String schema) { - Map listTable = new HashMap(); - try { - String query = "SELECT T.TABLE_NAME, T.TABLE_SCHEMA " + - "FROM information_schema.tables T WHERE TABLE_SCHEMA = '" + schema + "' and TABLE_TYPE = 'BASE TABLE'"; - Connection connect = getConnection(); - - Statement stmt = connect.createStatement(); + final Map listTable = new HashMap<>(); + final String query = + "SELECT T.TABLE_NAME, T.TABLE_SCHEMA " + + "FROM information_schema.tables T WHERE TABLE_SCHEMA = '" + schema + "' and TABLE_TYPE = 'BASE TABLE'"; + + try ( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); - + ){ + while(rs.next()){ - String nameTable = rs.getString("TABLE_NAME"); - DBTable table = new DBTable(nameTable); - table.setSchema(schema); - rowToProperties(rs, table.getOptions()); - - Statement stmtDdl = connect.createStatement(); - ResultSet rsDdl = stmtDdl.executeQuery("show create table " + schema + ".`" + nameTable + "`"); - rsDdl.next(); - - table.getOptions().addChild("ddl", cleanString(rsDdl.getString(2))); - + //TODO retrieve table comment + //TODO retrieve table owner + + final String nameTable = rs.getString("TABLE_NAME"); + final String ownerTable = ""; + final String commentTable = ""; + final String ddlQuery = "show create table " + schema + ".`" + nameTable + "`"; + final StringProperties options = new StringProperties(rs); + final Set dependencies = rs.getArray("dependencies") != null + ? new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())) + : Collections.emptySet(); + + try( + Statement stmtDdl = getConnection().createStatement(); + ResultSet rsDdl = stmtDdl.executeQuery(ddlQuery); + ){ + if(!rsDdl.next()) throw new ExceptionDBGitRunTime("failed to get table ddl resultset"); + options.addChild("ddl", cleanString(rsDdl.getString(2))); + } + + final DBTable table = new DBTable(nameTable, options, schema, ownerTable, dependencies, commentTable); listTable.put(nameTable, table); - - stmtDdl.close(); - rsDdl.close(); + } - rs.close(); - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listTable; } @Override public DBTable getTable(String schema, String name) { - try { - String query = "SELECT T.TABLE_NAME, T.TABLE_SCHEMA " + - "FROM information_schema.tables T WHERE TABLE_SCHEMA = '" + schema + "' AND T.TABLE_NAME = '" + name + "'"; - Connection connect = getConnection(); - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final String query = + "SELECT T.TABLE_NAME, T.TABLE_SCHEMA FROM information_schema.tables T" + + " WHERE TABLE_SCHEMA = '" + schema + "'" + + " AND T.TABLE_NAME = '" + name + "'"; - DBTable table = null; - - while(rs.next()) { - String nameTable = rs.getString("TABLE_NAME"); - table = new DBTable(nameTable); - table.setSchema(schema); - - Statement stmtDdl = connect.createStatement(); - ResultSet rsDdl = stmtDdl.executeQuery("show create table " + schema + ".`" + nameTable + "`"); - rsDdl.next(); - table.getOptions().addChild("ddl", cleanString(rsDdl.getString(2))); - rowToProperties(rs, table.getOptions()); - stmtDdl.close(); - rsDdl.close(); + try (Statement stmt = connect.createStatement(); ResultSet rs = stmt.executeQuery(query);){ + + if (rs.next()){ + //TODO retrieve table comment + //TODO retrieve table owner + final String nameTable = rs.getString("TABLE_NAME"); + final String ownerTable = ""; + final String commentTable = ""; + final StringProperties options = new StringProperties(rs); + final Set dependencies = rs.getArray("dependencies") != null + ? new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())) + : Collections.emptySet(); + + final String ddlQuery = "show create table " + schema + ".`" + nameTable + "`"; + try(Statement stmtDdl = getConnection().createStatement(); ResultSet rsDdl = stmtDdl.executeQuery(ddlQuery);){ + rsDdl.next(); + options.addChild("ddl", cleanString(rsDdl.getString(2))); + } + return new DBTable(nameTable, options, schema, ownerTable, dependencies, commentTable); + + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - rs.close(); - stmt.close(); - - return table; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + + } catch(Exception e) { + String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + } @Override public Map getTableFields(String schema, String nameTable) { - try { - Map listField = new HashMap(); - - String query = - "SELECT distinct col.column_name,col.is_nullable,col.data_type,col.character_maximum_length, tc.constraint_name, " + - "case\r\n" + - " when lower(data_type) in ('tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'float', 'double', 'decimal') then 'number' \r\n" + - " when lower(data_type) in ('tinytext', 'text', 'char', 'mediumtext', 'longtext', 'varchar') then 'string'\r\n" + - " when lower(data_type) in ('datetime', 'timestamp', 'date') then 'date'\r\n" + - " when lower(data_type) in ('boolean') then 'boolean'\r\n" + - " when lower(data_type) in ('blob', 'mediumblob', 'longblob', 'binary', 'varbinary') then 'binary'" + - " else 'native'\r\n" + - " end tp, " + - " case when lower(data_type) in ('char', 'character') then true else false end fixed, " + - "col.* FROM " + - "information_schema.columns col " + - "left join information_schema.key_column_usage kc on col.table_schema = kc.table_schema and col.table_name = kc.table_name and col.column_name=kc.column_name " + - "left join information_schema.table_constraints tc on col.table_schema = kc.table_schema and col.table_name = kc.table_name and kc.constraint_name = tc.constraint_name and tc.constraint_type = 'PRIMARY KEY' " + - "where col.table_schema = :schema and col.table_name = :table " + - "order by col.column_name "; - Connection connect = getConnection(); - - NamedParameterPreparedStatement stmt = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(connect, query); - stmt.setString("schema", schema); - stmt.setString("table", nameTable); + final Map listField = new HashMap(); + final String query = + "SELECT DISTINCT " + + " col.column_name, col.is_nullable, col.data_type, col.character_maximum_length, tc.constraint_name, " + + " case\r\n" + + " when lower(data_type) in ('tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'float', 'double', 'decimal') then 'number' \r\n" + + " when lower(data_type) in ('tinytext', 'text', 'char', 'mediumtext', 'longtext', 'varchar') then 'string'\r\n" + + " when lower(data_type) in ('datetime', 'timestamp', 'date') then 'date'\r\n" + + " when lower(data_type) in ('boolean') then 'boolean'\r\n" + + " when lower(data_type) in ('blob', 'mediumblob', 'longblob', 'binary', 'varbinary') then 'binary'" + + " else 'native'\r\n" + + " end tp, " + + " case " + + " when lower(data_type) in ('char', 'character') " + + " then true else false " + + " end fixed, " + + " col.* " + + "FROM information_schema.columns col " + + "LEFT JOIN information_schema.key_column_usage kc on col.table_schema = kc.table_schema and col.table_name = kc.table_name and col.column_name=kc.column_name " + + "LEFT JOIN information_schema.table_constraints tc on col.table_schema = kc.table_schema and col.table_name = kc.table_name and kc.constraint_name = tc.constraint_name and tc.constraint_type = 'PRIMARY KEY' " + + "WHERE col.table_schema = :schema and col.table_name = :table " + + "ORDER BY col.column_name "; + try ( + PreparedStatement stmt = preparedStatement(getConnection(), query, ImmutableMap.of("schema", schema, "table", nameTable)); ResultSet rs = stmt.executeQuery(); - while(rs.next()){ - DBTableField field = new DBTableField(); - field.setName(rs.getString("column_name").toLowerCase()); - if (rs.getString("constraint_name") != null) { - field.setIsPrimaryKey(true); - } - String typeSQL = getFieldType(rs); - field.setTypeSQL(typeSQL); - field.setIsNullable( !typeSQL.toLowerCase().contains("not null")); - field.setTypeUniversal(FieldType.fromString(rs.getString("tp"))); - field.setFixed(false); - field.setLength(rs.getInt("character_maximum_length")); - field.setPrecision(rs.getInt("numeric_precision")); - field.setScale(rs.getInt("numeric_scale")); - field.setFixed(rs.getBoolean("fixed")); + ) { + + while(rs.next()){ + + //TODO make restore defaultValue, description (comment) and order in MySQL + final String columnName = rs.getString("column_name").toLowerCase(); + final String typeSQL = getFieldType(rs); + final FieldType typeUniversal = FieldType.fromString(rs.getString("tp")); + final String defaultValue = rs.getString("column_name") != null ? rs.getString("column_name").toLowerCase() : ""; + final String description = rs.getString("column_comment") != null ? rs.getString("column_comment").toLowerCase() : ""; + final int order = rs.getInt("ordinal_position"); + final boolean isPrimaryKey = rs.getString("constraint_name") != null; + final boolean isFixed = rs.getBoolean("isFixed"); + final boolean isNullable = !typeSQL.toLowerCase().contains("not null"); + final int length = rs.getInt("character_maximum_length"); + final int precision = rs.getInt("numeric_precision"); + final int scale = rs.getInt("numeric_scale"); + + final DBTableField field = new DBTableField( + columnName, description, isPrimaryKey, isNullable, + typeSQL, typeUniversal, order, defaultValue, + length, scale, precision, isFixed + ); + listField.put(field.getName(), field); } - stmt.close(); - - return listField; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); - } + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); + } + + return listField; } @Override public Map getIndexes(String schema, String nameTable) { - try { - Map indexes = new HashMap<>(); - String query = "select TABLE_NAME, INDEX_NAME, INDEX_TYPE, NON_UNIQUE, GROUP_CONCAT(COLUMN_NAME separator '`, `') as FIELDS " - + "from INFORMATION_SCHEMA.STATISTICS where TABLE_SCHEMA = '" + schema + "' and INDEX_NAME != 'PRIMARY' " - + "group by TABLE_NAME, INDEX_NAME, INDEX_TYPE, NON_UNIQUE order by TABLE_NAME, INDEX_NAME;"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + final Map indexes = new HashMap<>(); + final String query = + "select TABLE_NAME, INDEX_NAME, INDEX_TYPE, NON_UNIQUE, GROUP_CONCAT(COLUMN_NAME separator '`, `') as FIELDS " + + "from INFORMATION_SCHEMA.STATISTICS where TABLE_SCHEMA = '" + schema + "' and INDEX_NAME != 'PRIMARY' " + + "group by TABLE_NAME, INDEX_NAME, INDEX_TYPE, NON_UNIQUE order by TABLE_NAME, INDEX_NAME;"; + + try( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ) { + while(rs.next()) { - DBIndex index = new DBIndex(rs.getString("INDEX_NAME")); - index.setSchema(schema); - index.setOwner(schema); - rowToProperties(rs, index.getOptions()); - - String ddl = "create " + (rs.getInt("NON_UNIQUE") == 1 ? "" : "unique ") - + "index `" + rs.getString("INDEX_NAME") - + "` using " + rs.getString("INDEX_TYPE") - + " on " + schema + ".`" + rs.getString("TABLE_NAME") + "`" - + "(`" + rs.getString("FIELDS") + "`)"; - - index.getOptions().addChild("ddl", cleanString(ddl)); - indexes.put(rs.getString("INDEX_NAME"), index); + + //TODO find real owner + final String indexName = rs.getString("INDEX_NAME"); + final String sql = cleanString( + "create " + (rs.getInt("NON_UNIQUE") == 1 ? "" : "unique ") + + "index `" + indexName + + "` using " + rs.getString("INDEX_TYPE") + + " on " + schema + ".`" + rs.getString("TABLE_NAME") + "`" + + "(`" + rs.getString("FIELDS") + "`)" + ); + + final DBIndex index = new DBIndex(indexName, new StringProperties(rs), schema, schema, Collections.emptySet(), sql); + indexes.put(indexName, index); } - stmt.close(); - return indexes; + } catch(Exception e) { - logger.error(e.getMessage()); - System.out.println(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); + final String msg = lang.getValue("errors", "adapter", "indexes").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + + return indexes; } @Override public Map getConstraints(String schema, String nameTable) { - Map constraints = new HashMap<>(); - return constraints; + return Collections.emptyMap(); } @Override public Map getViews(String schema) { - Map listView = new HashMap(); - try { - String query = "show full tables in " + schema + " where TABLE_TYPE like 'VIEW'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + final Map listView = new HashMap(); + final String query = "show full tables in " + schema + " where TABLE_TYPE like 'VIEW'"; + + try ( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ) { + while(rs.next()){ - DBView view = new DBView(rs.getString(1)); - view.setSchema(schema); - view.setOwner(schema); - rowToProperties(rs, view.getOptions()); - - Statement stmtDdl = connect.createStatement(); - ResultSet rsDdl = stmtDdl.executeQuery("show create view " + schema + "." + rs.getString(1)); - rsDdl.next(); - - view.getOptions().addChild("ddl", cleanString(rsDdl.getString(2))); - listView.put(rs.getString(1), view); - - stmtDdl.close(); - rsDdl.close(); + + //TODO try find real owner + final String name = rs.getString(1); + final String ddlQuery = "show create view " + schema + "." + name; + String sql = ""; + + try( + Statement stmtDdl = getConnection().createStatement(); + ResultSet rsDdl = stmtDdl.executeQuery(ddlQuery); + ){ + if(rsDdl.next()){ + sql = cleanString(rsDdl.getString(2)); + } else { + String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + } + + final DBView view = new DBView(name, new StringProperties(rs), schema, schema, Collections.emptySet(), sql); + listView.put(name, view); } - stmt.close(); - return listView; + } catch(Exception e) { - logger.error(e.getMessage()); - System.out.println(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); + final DBGitLang msg = lang.getValue("errors", "adapter", "views"); + throw new ExceptionDBGitRunTime(msg, e); } + + return listView; + } @Override public DBView getView(String schema, String name) { - DBView view = new DBView(name); - view.setSchema(schema); - view.setOwner(schema); - try { - Statement stmtDdl = connect.createStatement(); - ResultSet rsDdl = stmtDdl.executeQuery("show create view " + schema + ".`" + name + "`"); - if(rsDdl.next()) - view.getOptions().addChild("ddl", cleanString(rsDdl.getString(2))); - stmtDdl.close(); - rsDdl.close(); - return view; - }catch(Exception e) { - logger.error(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); + //TODO find real owner + final String query = "show create view " + schema + ".`" + name + "`"; + + try ( + Statement stmtDdl = getConnection().createStatement(); + ResultSet rsDdl = stmtDdl.executeQuery(query); + ) { + + if(rsDdl.next()) { + final String sql = cleanString(rsDdl.getString(2)); + return new DBView(name, new StringProperties(rsDdl), schema, schema, Collections.emptySet(), sql); + } else { + String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + } catch(Exception e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "views"); + throw new ExceptionDBGitRunTime(msg, e); } - + } @Override public Map getPackages(String schema) { - Map packages = new HashMap(); - return packages; + return Collections.emptyMap(); } @Override public DBPackage getPackage(String schema, String name) { - // TODO Auto-generated method stub - return null; + throw new ExceptionDBGitRunTime(new ExceptionDBGitObjectNotFound("cannot get packages on mysql")); } @Override public Map getProcedures(String schema) { - Map procedures = new HashMap(); - return procedures; + return Collections.emptyMap(); } @Override public DBProcedure getProcedure(String schema, String name) { - // TODO Auto-generated method stub - return null; + throw new ExceptionDBGitRunTime(new ExceptionDBGitObjectNotFound("cannot get procedure on mysql")); } @Override public Map getFunctions(String schema) { - Map listFunction = new HashMap(); - try { - String query = "SELECT R.routine_schema as \"schema\", R.definer as \"rolname\", R.specific_name as \"name\"," + - "group_concat(concat(P.parameter_name, \" \", P.data_type)) as \"arguments\", R.routine_definition as \"ddl\"\r\n" + - "FROM information_schema.routines as R, information_schema.parameters as P\r\n" + - "WHERE P.parameter_mode='IN' and P.routine_type=R.routine_type and P.specific_schema=R.routine_schema and\r\n" + - "P.specific_name=R.specific_name and R.routine_type='FUNCTION' and R.routine_schema='" + schema + "' GROUP BY R.specific_name,1,2,5,P.ordinal_position ORDER BY P.ordinal_position"; + final Map listFunction = new HashMap(); + final String query = + "SELECT R.routine_schema as \"schema\", R.definer as \"rolname\", R.specific_name as \"name\"," + + "group_concat(concat(P.parameter_name, \" \", P.data_type)) as \"arguments\", R.routine_definition as \"ddl\"\r\n" + + "FROM information_schema.routines as R, information_schema.parameters as P\r\n" + + "WHERE P.parameter_mode='IN' and P.routine_type=R.routine_type and P.specific_schema=R.routine_schema and\r\n" + + "P.specific_name=R.specific_name and R.routine_type='FUNCTION' and R.routine_schema='" + schema + "'" + + " GROUP BY R.specific_name,1,2,5,P.ordinal_position ORDER BY P.ordinal_position"; + + try ( Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ) { + while(rs.next()) { - String name = rs.getString("name"); - String owner = rs.getString("rolname"); - String args = rs.getString("arguments"); - DBFunction func = new DBFunction(name); - func.setSchema(schema); - func.setOwner(owner); - rowToProperties(rs, func.getOptions()); + final String name = rs.getString("name"); + final String owner = rs.getString("rolname"); + final String sql = rs.getString("ddl"); + + DBFunction func = new DBFunction(name, new StringProperties(rs), schema, owner, Collections.emptySet(), sql); + //String args = rs.getString("arguments"); //func.setArguments(args); listFunction.put(name, func); } - stmt.close(); + } catch(Exception e) { throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "fnc").toString(), e); } + return listFunction; } @Override public DBFunction getFunction(String schema, String name) { - DBFunction function = new DBFunction(name); - try { - String query = "SELECT R.routine_schema as \"schema\", R.definer as \"rolname\", R.specific_name as \"name\"," + - "group_concat(concat(P.parameter_name, \" \", P.data_type)) as \"arguments\", R.routine_definition as \"ddl\"\r\n" + - "FROM information_schema.routines as R, information_schema.parameters as P\r\n" + - "WHERE P.parameter_mode='IN' and P.routine_type=R.routine_type and P.specific_schema=R.routine_schema and\r\n" + - "P.specific_name=R.specific_name and R.routine_type='FUNCTION' and R.routine_schema='" + schema + "' and R.specific_name='" + name + "'\r\n" + - "GROUP BY R.specific_name,1,2,5,P.ordinal_position ORDER BY P.ordinal_position"; - Statement stmt = getConnection().createStatement(); - ResultSet rs = stmt.executeQuery(query); + final DBFunction function = null; + + final String query = + "SELECT R.routine_schema as \"schema\", R.definer as \"rolname\", R.specific_name as \"name\"," + + "group_concat(concat(P.parameter_name, \" \", P.data_type)) as \"arguments\", R.routine_definition as \"ddl\"\r\n" + + "FROM information_schema.routines as R, information_schema.parameters as P\r\n" + + "WHERE P.parameter_mode='IN' and P.routine_type=R.routine_type and P.specific_schema=R.routine_schema and\r\n" + + "P.specific_name=R.specific_name and R.routine_type='FUNCTION' and R.routine_schema='" + schema + "'" + + " and R.specific_name='" + name + "'\r\n" + + "GROUP BY R.specific_name,1,2,5,P.ordinal_position ORDER BY P.ordinal_position"; + + try ( + Statement stmt = getConnection().createStatement(); + ResultSet rs = stmt.executeQuery(query); + ) { + if(rs.next()) { - String owner = rs.getString("rolname"); - String args = rs.getString("arguments"); - function.setSchema(schema); - function.setOwner(owner); - rowToProperties(rs, function.getOptions()); + final String owner = rs.getString("rolname"); + final String sql = rs.getString("ddl"); + + //String args = rs.getString("arguments"); //function.setArguments(args); + return new DBFunction(name, new StringProperties(rs), schema, owner, Collections.emptySet(), sql); + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - stmt.close(); - } catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "fnc").toString(), e); + + } catch (Exception e) { + final String msg = lang.getValue("errors", "adapter", "fnc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } - return function; + } @Override public Map getTriggers(String schema) { - Map listTrigger = new HashMap(); - try { - String query = "show triggers in " + schema; - - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + + final Map listTrigger = new HashMap(); + final String query = "show triggers in " + schema; + + try ( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ) { while(rs.next()){ - String name = rs.getString(1); - DBTrigger trigger = new DBTrigger(name); - trigger.setSchema(schema); - trigger.setOwner(schema); - - Statement stmtDdl = connect.createStatement(); - ResultSet rsDdl = stmtDdl.executeQuery("show create trigger " + schema + "." + rs.getString(1)); - rsDdl.next(); - - trigger.getOptions().addChild("ddl", cleanString(rsDdl.getString(3))); - - stmtDdl.close(); - rsDdl.close(); - - rowToProperties(rs, trigger.getOptions()); - listTrigger.put(name, trigger); + //TODO find real owner + final String name = rs.getString(1); + final String ddlQuery = "show create trigger " + schema + "." + name; + + try( + Statement stmtDdl = getConnection().createStatement(); + ResultSet rsDdl = stmtDdl.executeQuery(ddlQuery); + ){ + if(!rsDdl.next()) throw new ExceptionDBGitRunTime("failed to get ddl resultset"); + + final String sql = rsDdl.getString(3); + final StringProperties options = new StringProperties(rs); + final DBTrigger trigger = new DBTrigger(name, options, schema, schema, Collections.emptySet(), sql); + + listTrigger.put(name, trigger); + } + } - stmt.close(); - return listTrigger; - }catch(Exception e) { - throw new ExceptionDBGitRunTime(e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "triggers").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + + return listTrigger; } @Override public DBTrigger getTrigger(String schema, String name) { - DBTrigger trigger = new DBTrigger(name); - try { - trigger.setSchema(schema); - trigger.setOwner(schema); - - Statement stmtDdl = connect.createStatement(); - ResultSet rsDdl = stmtDdl.executeQuery("show create trigger " + schema + "." + name); - rsDdl.next(); - - trigger.getOptions().addChild("ddl", cleanString(rsDdl.getString(3))); - - stmtDdl.close(); - rsDdl.close(); - - return trigger; - - }catch(Exception e) { - throw new ExceptionDBGitRunTime(e); + final String query = "show create trigger " + schema + "." + name; + + try ( + Statement stmtDdl = getConnection().createStatement(); + ResultSet rsDdl = stmtDdl.executeQuery(query); + ) { + + if(rsDdl.next()){ + + final StringProperties options = new StringProperties(rsDdl); + final String sql = rsDdl.getString("SQL Original Statement"); + return new DBTrigger(name, options, schema, schema, Collections.emptySet(), sql); + + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + } catch(Exception e) { + throw new ExceptionDBGitRunTime(e); } + } @Override public DBTableData getTableData(String schema, String nameTable) { - String tableName = schema + ".`" + nameTable + "`"; try { - DBTableData data = new DBTableData(); - - int maxRowsCount = DBGitConfig.getInstance().getInteger("core", "MAX_ROW_COUNT_FETCH", DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH)); - - if (DBGitConfig.getInstance().getBoolean("core", "LIMIT_FETCH", DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true))) { - Statement st = getConnection().createStatement(); - String query = "select COALESCE(count(*), 0) kolvo from ( select 1 from "+ - tableName + " limit " + (maxRowsCount + 1) + " ) tbl"; - ResultSet rs = st.executeQuery(query); - rs.next(); - if (rs.getInt("kolvo") > maxRowsCount) { - data.setErrorFlag(DBTableData.ERROR_LIMIT_ROWS); - return data; + + final int maxRowsCount = DBGitConfig.getInstance().getInteger( + "core", "MAX_ROW_COUNT_FETCH", + DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH) + ); + final boolean toLimitFetch = DBGitConfig.getInstance().getBoolean( + "core", "LIMIT_FETCH", + DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true) + ); + + final String tableName = schema + ".`" + nameTable + "`"; + final String dataQuery = "select * from " + tableName; + final String rowsCountQuery = + "select COALESCE(count(*), 0) kolvo " + + "from ( " + + " select 1 " + + " from " + tableName + " " + + " limit " + (maxRowsCount + 1) + " " + + ") tbl"; + + if (toLimitFetch) { + + try ( + Statement st = getConnection().createStatement(); + ResultSet rs = st.executeQuery(rowsCountQuery); + ){ + if(!rs.next()) throw new ExceptionDBGitRunTime("Could not execute rows count query"); + if (rs.getInt("kolvo") > maxRowsCount) { + return new DBTableData(DBTableData.ERROR_LIMIT_ROWS); + } } - - rs = st.executeQuery("select * from "+tableName); - data.setResultSet(rs); - return data; + } - - return data; + return new DBTableData(getConnection(), dataQuery); + + } catch(Exception e) { + final String msg = DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); + } + } + + @Override + public DBTableData getTableDataPortion(String schema, String nameTable, int portionIndex, int tryNumber) { + final int portionSize = DBGitConfig.getInstance().getInteger("core", "PORTION_SIZE", DBGitConfig.getInstance().getIntegerGlobal("core", "PORTION_SIZE", 1000)); + final int beginRowNum = 1 + portionSize * portionIndex; + final int endRowNum = portionSize + portionSize * portionIndex; + + final String dataQuery = + "SELECT * " + "\n" + + "FROM (" + "\n" + + " SELECT " + "\n" + + " f.*, " + "\n" + + " ROW_NUMBER() OVER (" + "\n" + + " ORDER BY (" + "\n" + + " select group_concat(column_name separator ', ') " + "\n" + + " from information_schema.columns " + "\n" + + " where table_schema='" + schema + "' " + "\n" + + " and table_name='" + nameTable + "' " + "\n" + + " and upper(column_key)='PRI'" + "\n" + + " )" + "\n" + + " ) DBGIT_ROW_NUM " + "\n" + + " FROM " + schema + "." + nameTable + " f" + "\n" + + ") s \n" + + "WHERE DBGIT_ROW_NUM BETWEEN " + beginRowNum + " AND " + endRowNum; + + try { + + return new DBTableData(getConnection(), dataQuery); + } catch(Exception e) { + + final int maxTriesCount = DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000)); + final int tryDelay = DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000)); + + ConsoleWriter.println(e.getLocalizedMessage(), messageLevel); + ConsoleWriter.detailsPrintln(ExceptionUtils.getStackTrace(e), messageLevel); logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - try { - getConnection().rollback(); - } catch (Exception e2) { - logger.error(lang.getValue("errors", "adapter", "rollback").toString(), e2); + + if (tryNumber <= maxTriesCount) { + + final String waitMessage = DBGitLang.getInstance() + .getValue("errors", "dataTable", "wait") + .withParams(String.valueOf(tryDelay)); + + final String tryAgainMessage = DBGitLang.getInstance() + .getValue("errors", "dataTable", "tryAgain") + .withParams(String.valueOf(tryNumber)); + + ConsoleWriter.println(waitMessage, messageLevel); + try { TimeUnit.SECONDS.sleep(tryDelay); } catch (InterruptedException e1) { + throw new ExceptionDBGitRunTime(e1.getMessage()); + } + + ConsoleWriter.println(tryAgainMessage, messageLevel); + return getTableDataPortion(schema, nameTable, portionIndex, tryNumber++); + + } else { + final String msg = DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); } - throw new ExceptionDBGitRunTime(e.getMessage()); + } } @Override public Map getUsers() { - Map users = new HashMap(); - try { - String query = "select User, authentication_string from mysql.user"; + final Map users = new HashMap(); + final String query = "select User, authentication_string from mysql.user"; + + try ( Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ) { + while(rs.next()) { - String name = rs.getString(1); - String password = rs.getString(2); - StringProperties options = new StringProperties(); + final String name = rs.getString(1); + final String password = rs.getString(2); + final StringProperties options = new StringProperties(); options.addChild("password", password); - DBUser user = new DBUser(name, options); + + final DBUser user = new DBUser(name, options); users.put(name, user); } - stmt.close(); - }catch(Exception e) { - logger.error(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); + + } catch(Exception e) { + throw new ExceptionDBGitRunTime(e); } + return users; } @Override - public Map getRoles() { - Map roles = new HashMap(); - return roles; - } + public Map getRoles() { return Collections.emptyMap(); } @Override - public boolean userHasRightsToGetDdlOfOtherUsers() { - return true; + public Map getUDTs(String schema) { + return Collections.emptyMap(); } @Override - public IFactoryDBBackupAdapter getBackupAdapterFactory() { - return backupFactory; + public Map getDomains(String schema) { + return Collections.emptyMap(); } @Override - public DbType getDbType() { - return DbType.MYSQL; + public Map getEnums(String schema) { + return Collections.emptyMap(); } @Override - public String getDbVersion() { - try { - PreparedStatement stmt = getConnection().prepareStatement("SELECT version()"); - ResultSet resultSet = stmt.executeQuery(); - resultSet.next(); - - String result = resultSet.getString(1); - resultSet.close(); - stmt.close(); - - return result; - } catch (SQLException e) { - return ""; - } + public DBUserDefinedType getUDT(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } @Override - public void createSchemaIfNeed(String schemaName) throws ExceptionDBGit { - try { - Statement st = connect.createStatement(); - ResultSet rs = st.executeQuery("select count(*) cnt from information_schema.schemata where upper(schema_name) = '" + - schemaName.toUpperCase() + "'"); - - rs.next(); - if (rs.getInt("cnt") == 0) { - StatementLogging stLog = new StatementLogging(connect, getStreamOutputSqlCommand(), isExecSql()); - stLog.execute("create schema " + schemaName); - - stLog.close(); - } - - rs.close(); - st.close(); - } catch (SQLException e) { - throw new ExceptionDBGit(lang.getValue("errors", "adapter", "createSchema") + ": " + e.getLocalizedMessage()); - } + public DBDomain getDomain(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } @Override - public void createRoleIfNeed(String roleName) throws ExceptionDBGit { - // TODO Auto-generated method stub - + 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 { - StringBuilder type = new StringBuilder(); - type.append(rs.getString("data_type")); - - BigDecimal max_length = rs.getBigDecimal("character_maximum_length"); + final StringBuilder type = new StringBuilder(); + if (!rs.wasNull()) { - type.append("(" + max_length + ")"); - } - if (rs.getString("is_nullable").equals("NO")){ - type.append(" NOT NULL"); + final String typePart = rs.getString("data_type"); + final String lengthPart = "(" + rs.getBigDecimal("character_maximum_length") + ")"; + final String nullablePart = rs.getString("is_nullable").equals("NO") ? " NOT NULL" : ""; + type.append( typePart ); + type.append( lengthPart ); + type.append( nullablePart ); } - - return type.toString(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); - } - } - - @Override - public String getDefaultScheme() throws ExceptionDBGit { - try { - return getConnection().getCatalog(); - } catch (SQLException e) { - throw new ExceptionDBGit(lang.getValue("errors", "adapter", "getSchema") + ": " + e.getLocalizedMessage()); - } - } - - @Override - public IFactoryDBConvertAdapter getConvertAdapterFactory() { - return convertFactory; - } - @Override - public boolean isReservedWord(String word) { - return reservedWords.contains(word.toUpperCase()); - } - - @Override - public DBTableData getTableDataPortion(String schema, String nameTable, int portionIndex, int tryNumber) { - DBTableData data = new DBTableData(); - try { - int portionSize = DBGitConfig.getInstance().getInteger("core", "PORTION_SIZE", DBGitConfig.getInstance().getIntegerGlobal("core", "PORTION_SIZE", 1000)); - - int begin = 1 + portionSize * portionIndex; - int end = portionSize + portionSize * portionIndex; - - Statement st = getConnection().createStatement(); - ResultSet rs = st.executeQuery("SELECT * FROM \r\n" + - "(SELECT f.*, ROW_NUMBER() OVER (ORDER BY (select group_concat(column_name separator ', ') from information_schema.columns where \r\n" + - "table_schema='" + schema + "' and table_name='" + nameTable + "' and upper(column_key)='PRI')) DBGIT_ROW_NUM FROM " + schema + "." + nameTable + " f) s \r\n" + - "WHERE DBGIT_ROW_NUM BETWEEN " + begin + " and " + end); - data.setResultSet(rs); - return data; + return type.toString(); } catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - - try { - if (tryNumber <= DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000))) { - try { - TimeUnit.SECONDS.sleep(DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000))); - } catch (InterruptedException e1) { - throw new ExceptionDBGitRunTime(e1.getMessage()); - } - ConsoleWriter.println("Error while getting portion of data, try " + tryNumber); - getTableDataPortion(schema, nameTable, portionIndex, tryNumber++); - } - } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - try { - getConnection().rollback(); - } catch (Exception e2) { - logger.error(lang.getValue("errors", "adapter", "rollback").toString(), e2); - } - throw new ExceptionDBGitRunTime(e.getMessage()); + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } + private NamedParameterPreparedStatement getParamStatement(String query) throws SQLException { + return NamedParameterPreparedStatement.createNamedParameterPreparedStatement(getConnection(), query); + } static { - reservedWords = new HashSet<>(); reservedWords.add("ACCESSIBLE"); reservedWords.add("ACCOUNT"); reservedWords.add("ACTION"); diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/DBBackupAdapterMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/DBBackupAdapterMySql.java index a88c165..d5556ab 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/DBBackupAdapterMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/DBBackupAdapterMySql.java @@ -36,7 +36,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws Exception { if (isSaveToSchema()) { createSchema(stLog, schema); } - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); ////dropIfExists(isSaveToSchema() ? PREFIX + schema : schema, //// isSaveToSchema() ? objectName : PREFIX + objectName, stLog); //ddl = ddl.replace(schema + "." + objectName, getFullDbName(schema, objectName)); @@ -45,7 +45,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws Exception { File file = new File(DBGitPath.getFullPath() + metaSql.getFileName()); if (file.exists()) obj = metaSql.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else if (obj instanceof MetaTable) { MetaTable metaTable = (MetaTable) obj; metaTable.loadFromDB(); @@ -64,7 +64,9 @@ public IMetaObject backupDBObject(IMetaObject obj) throws Exception { if (isSaveToSchema()) { createSchema(stLog, schema); } - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(tableName, getFullDbName(schema, tableName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(tableName, getFullDbName(schema, tableName)) + , messageLevel + ); //dropIfExists( //isSaveToSchema() ? PREFIX + schema : schema, //isSaveToSchema() ? tableName : PREFIX + tableName, stLog @@ -108,7 +110,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws Exception { File file = new File(DBGitPath.getFullPath() + metaTable.getFileName()); if (file.exists()) obj = metaTable.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else if (obj instanceof MetaSequence) { MetaSequence metaSequence = (MetaSequence) obj; metaSequence.loadFromDB(); @@ -118,7 +120,9 @@ public IMetaObject backupDBObject(IMetaObject obj) throws Exception { createSchema(stLog, schema); } String sequenceName = getFullDbName(schema, objectName); - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)) + , messageLevel + ); //String ddl = "create sequence " + sequenceName + "\n" //+ (metaSequence.getSequence().getOptions().get("cycle_option").toString().equals("YES") ? "CYCLE\n" : "") //+ " INCREMENT " + metaSequence.getSequence().getOptions().get("increment").toString() + "\n" @@ -134,14 +138,9 @@ public IMetaObject backupDBObject(IMetaObject obj) throws Exception { File file = new File(DBGitPath.getFullPath() + metaSequence.getFileName()); if (file.exists()) obj = metaSequence.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } - } catch (SQLException e1) { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError"). - withParams(obj.getName() + ": " + e1.getLocalizedMessage())); } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - connection.rollback(); throw new ExceptionDBGitRestore(lang.getValue("errors", "backup", "backupError").withParams(obj.getName()), e); } finally { connection.commit(); @@ -205,7 +204,7 @@ public void dropIfExists(IMetaObject imo, StatementLogging stLog) throws SQLExce stLog.execute(MessageFormat.format("DROP {0} {1}.{2}", rs.getString("tp"), nm.getSchema(), - DBAdapterMySql.escapeNameIfNeeded(nm.getName())) + adapter.escapeNameIfNeeded(nm.getName())) ); } @@ -223,7 +222,7 @@ public boolean createSchema(StatementLogging stLog, String schema) { rs.next(); if (rs.getInt("cnt") == 0) { - ConsoleWriter.detailsPrintLn(lang.getValue("general", "backup", "creatingSchema").withParams(PREFIX + schema)); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "creatingSchema").withParams(PREFIX + schema), messageLevel); stLog.execute("create schema " + PREFIX + schema); } @@ -232,7 +231,7 @@ public boolean createSchema(StatementLogging stLog, String schema) { return true; } catch (SQLException e) { - ConsoleWriter.println(lang.getValue("errors", "backup", "cannotCreateSchema").withParams(e.getLocalizedMessage())); + ConsoleWriter.println(lang.getValue("errors", "backup", "cannotCreateSchema").withParams(e.getLocalizedMessage()), messageLevel); return false; } } diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreSchemaMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreSchemaMySql.java index a300130..c4f2e8d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreSchemaMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreSchemaMySql.java @@ -17,20 +17,21 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreSchema").withParams(obj.getName()), 1); try { if (obj instanceof MetaSchema) { MetaSchema restoreSchema = (MetaSchema) obj; st.execute("CREATE SCHEMA IF NOT EXISTS " + restoreSchema.getObjectOption().getName()); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "schema", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return false; diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreTableDataMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreTableDataMySql.java index c1697ed..bf1da5e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreTableDataMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreTableDataMySql.java @@ -54,7 +54,7 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { currentTableData.getmapRows().clear(); if (getAdapter().getTable(schema, currentTableData.getTable().getName()) != null) { currentTableData.setDataTable(getAdapter().getTableData(schema, currentTableData.getTable().getName())); - ResultSet rs = currentTableData.getDataTable().getResultSet(); + ResultSet rs = currentTableData.getDataTable().resultSet(); TreeMapRowData mapRows = new TreeMapRowData(); MetaTable metaTable = new MetaTable(currentTableData.getTable()); metaTable.loadFromDB(currentTableData.getTable()); @@ -75,12 +75,16 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } return true; } else { - ////TODO WTF???? - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - //return true; + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table data cached", obj.getType().getValue() + )); } } else { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table data", obj.getType().getValue() + )); } } @@ -100,20 +104,19 @@ public void restoreTableDataMySql(MetaTableData restoreTableData, MetaTableData String schema = getPhisicalSchema(restoreTableData.getTable().getSchema()); schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); String tblName = schema + ".`" + restoreTableData.getTable().getName() + "`"; - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "tableData").withParams(tblName) + "\n", 1); if (!diffTableData.entriesOnlyOnLeft().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "inserting"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "inserting"), messageLevel); for (RowData rowData : diffTableData.entriesOnlyOnLeft().values()) { String fields = String.join("`, `", rowData.getData().keySet()); String values = String.join(", ", rowData.getData().values().stream().map(row -> valueToString(row)).collect(Collectors.toList())); String insertQuery = "insert into " + tblName + "(`" + fields + "`) values (" + values + ");"; - ConsoleWriter.detailsPrintLn(insertQuery); + ConsoleWriter.detailsPrintln(insertQuery, messageLevel); st.execute(insertQuery); } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } if (!diffTableData.entriesOnlyOnRight().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "deleting"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "deleting"), messageLevel); String ddl = ""; for (RowData rowData : diffTableData.entriesOnlyOnRight().values()) { Map primarykeys = new HashMap(); @@ -136,10 +139,10 @@ public void restoreTableDataMySql(MetaTableData restoreTableData, MetaTableData if (!ddl.isEmpty()) st.execute("delete from " + tblName + " where " + ddl); } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } if (!diffTableData.entriesDiffering().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "updating"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "updating"), messageLevel); String updateQuery = ""; //Map primarykeys = new HashMap(); for (ValueDifference diffRowData : diffTableData.entriesDiffering().values()) { @@ -212,14 +215,14 @@ public void restoreTableDataMySql(MetaTableData restoreTableData, MetaTableData } } } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); if (!updateQuery.isEmpty()) { - ConsoleWriter.println(updateQuery); + //TODO not a real restore, just print + ConsoleWriter.println(updateQuery, messageLevel); //st.execute(updateQuery); } } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(restoreTableData.getTable().getSchema() + "." + restoreTableData.getTable().getName()), e); } finally { st.close(); @@ -231,7 +234,7 @@ private static String valueToString(ICellData cell) { if(cell instanceof BooleanData) value += ((BooleanData) cell).getValue(); else if(cell instanceof LongData) - value += ((LongData) cell).getValue() != null ? String.valueOf(((LongData) cell).getValue()) : ""; + value += !((LongData) cell).isNull() ? String.valueOf(((LongData) cell).getValue()) : ""; else if(cell instanceof StringData) value += ((StringData) cell).getValue() != null ? ("'" + ((StringData) cell).getValue() .replace("\\", "\\\\") diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreTableMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreTableMySql.java index 29c79ff..699e1a4 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreTableMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreTableMySql.java @@ -54,7 +54,7 @@ public void removeMetaObject(IMetaObject obj) throws Exception { schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); st.execute("drop table if exists " + schema + "." + tbl.getName()); } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); + ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage()), 0); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); } finally { st.close(); @@ -64,15 +64,14 @@ public void removeMetaObject(IMetaObject obj) throws Exception { public void restoreTableMySql(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - try { + + try (StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql());){ if (obj instanceof MetaTable) { MetaTable restoreTable = (MetaTable) obj; String schema = getPhisicalSchema(restoreTable.getTable().getSchema().toLowerCase()); schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); String tblName = schema + ".`" + restoreTable.getTable().getName() + "`"; - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTable").withParams(tblName) + "\n", 1); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "createTable"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "createTable"), messageLevel); StringBuilder pk = new StringBuilder(); String ddl = "CREATE TABLE IF NOT EXISTS " + tblName + " (" + restoreTable @@ -84,27 +83,27 @@ public void restoreTableMySql(IMetaObject obj) throws Exception { if (f.getIsPrimaryKey()) pk.append(f.getName() + "`, `"); return "`" + f.getName() + "` " - + f.getTypeSQL() + (f.getFixed() ? "(" + f.getLength() + ")" : "") - + (f.getIsNullable() ? "" : " NOT NULL") - + (f.getDefaultValue() == null ? "" : - (f.getDefaultValue().toLowerCase().contains("nextval(") ? " AUTO_INCREMENT" : "")) - //+ (f.getDefaultValue() == null ? "" : " default " + f.getDefaultValue()) - + (f.getDescription() == null ? "" : " comment '" + f.getDescription() + "'"); + + f.getTypeSQL() + (f.getFixed() ? "(" + f.getLength() + ")" : "") + + (f.getIsNullable() ? "" : " NOT NULL") + + (f.getDefaultValue() == null ? "" : + (f.getDefaultValue().toLowerCase().contains("nextval(") ? " AUTO_INCREMENT" : "")) + //+ (f.getDefaultValue() == null ? "" : " default " + f.getDefaultValue()) + + (f.getDescription() == null ? "" : " comment '" + f.getDescription() + "'"); } ).collect(Collectors.joining(", ")) + (pk.length() > 1 ? ", PRIMARY KEY (`" + pk.replace(pk.length() - 4, pk.length(), "").toString() + "`)" : "") //FIXME: add foreign keys + ");"; st.execute(ddl); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - st.close(); } } @@ -112,7 +111,7 @@ public void restoreTableIndexesMySql(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreIndex").withParams(obj.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreIndex").withParams(obj.getName()), messageLevel); try { if (obj instanceof MetaTable) { MetaTable restoreTable = (MetaTable)obj; @@ -172,19 +171,18 @@ public void restoreTableIndexesMySql(IMetaObject obj) throws Exception { //} } else { String errText = lang.getValue("errors", "meta", "notFound").withParams(obj.getName()); - ConsoleWriter.detailsPrintlnRed(errText); throw new ExceptionDBGitRestore(errText); } } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } } @@ -193,7 +191,7 @@ private void restoreTableConstraintMySql(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreConstr").withParams(obj.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreConstr").withParams(obj.getName()), messageLevel); try { if (obj instanceof MetaTable) { MetaTable restoreTable = (MetaTable)obj; @@ -225,15 +223,15 @@ private void restoreTableConstraintMySql(IMetaObject obj) throws Exception { } } } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } } diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreUserMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreUserMySql.java index ddebfa7..4110a4b 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreUserMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreUserMySql.java @@ -16,7 +16,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreUser").withParams(obj.getName()), 1); try { if (obj instanceof MetaUser) { MetaUser usr = (MetaUser)obj; @@ -24,14 +23,15 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "user", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreViewMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreViewMySql.java index 56cedbd..76b1f2d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreViewMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/DBRestoreViewMySql.java @@ -17,22 +17,21 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreView").withParams(obj.getName()), 1); try { if (obj instanceof MetaView) { MetaView restoreView = (MetaView)obj; String ddl = restoreView.getSqlObject().getSql(); st.execute(ddl); - //connect.commit();//FIXME ???? } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "view", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/FactoryDBConvertAdapterMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/FactoryDBConvertAdapterMySql.java index b3444e0..3e42fa1 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/FactoryDBConvertAdapterMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/FactoryDBConvertAdapterMySql.java @@ -2,6 +2,7 @@ import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.meta.DBGitMetaType; import ru.fusionsoft.dbgit.mysql.converters.*; import ru.fusionsoft.dbgit.utils.ConsoleWriter; @@ -27,7 +28,11 @@ public class FactoryDBConvertAdapterMySql implements IFactoryDBConvertAdapter { @Override public IDBConvertAdapter getConvertAdapter(String objectType) throws Exception { if (!converters.containsKey(objectType)) { - ConsoleWriter.println("Cannot convert " + objectType + "!"); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("errors", "convert", "cannotConvert") + .withParams(objectType) + , 1 + ); return null; } else return converters.get(objectType); diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/FactoryDBRestoreAdapterMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/FactoryDBRestoreAdapterMySql.java index b55d02f..93a657d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/FactoryDBRestoreAdapterMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/FactoryDBRestoreAdapterMySql.java @@ -37,7 +37,7 @@ public class FactoryDBRestoreAdapterMySql implements IFactoryDBAdapterRestoteMet public IDBAdapterRestoreMetaData getAdapterRestore(IDBGitMetaType tp, IDBAdapter adapter) { if (!restoreAdapters.containsKey(tp.getValue())) { //return new DBRestoreMetaNotSupport(); - ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "restore", "cannotRestore").withParams(tp.getValue())); + ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "restore", "cannotRestore").withParams(tp.getValue()), messageLevel); return null; } diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/converters/SchemaConverterMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/converters/SchemaConverterMySql.java index 030c440..10a7453 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/converters/SchemaConverterMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/converters/SchemaConverterMySql.java @@ -2,6 +2,7 @@ import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; import ru.fusionsoft.dbgit.core.DBConnection; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.meta.IMetaObject; @@ -17,7 +18,11 @@ public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) thr if (obj instanceof MetaSchema) { MetaSchema schema = (MetaSchema) obj; schema.setDbType(DbType.MYSQL); - ConsoleWriter.println("Processing schema " + schema.getName()); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingSchema") + .withParams(schema.getName()) + , messageLevel + ); //ConsoleWriter.printlnGreen("URL=" + DBConnection.getInstance().dbName); switch(objDbType) { case POSTGRES: diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/converters/TableConverterMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/converters/TableConverterMySql.java index fa38060..aec60b1 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/converters/TableConverterMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/converters/TableConverterMySql.java @@ -1,6 +1,7 @@ package ru.fusionsoft.dbgit.mysql.converters; import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.dbobjects.DBConstraint; @@ -21,7 +22,11 @@ public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) thr return obj; if (obj instanceof MetaTable) { MetaTable table = (MetaTable) obj; - ConsoleWriter.println("Processing table " + table.getName()); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "processingTable") + .withParams(table.getName()) + , messageLevel + ); //types for (DBTableField field : table.getFields().values()) field.setTypeSQL(typeFromAnotherDB(objDbType, field)); @@ -56,17 +61,29 @@ public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) thr } private String indexFromPostgres(DBIndex index) { - ConsoleWriter.println("Converting table index " + index.getName() + " from postgresql to mysql..."); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingIndex") + .withParams(index.getName(), "postgresql", "mysql") + , messageLevel + ); return ""; } private String indexFromOracle(DBIndex index) { - ConsoleWriter.println("Converting table index " + index.getName() + " from oracle to mysql..."); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingIndex") + .withParams(index.getName(), "oracle", "mysql") + , messageLevel + ); return ""; } private String constraintFromOracle(DBConstraint constraint) {//TODO: change - ConsoleWriter.println("Converting table constraint " + constraint.getName() + " from oracle to mysql..."); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingConstraint") + .withParams(constraint.getName(), "oracle", "mysql") + , messageLevel + ); Pattern patternConstraint = Pattern.compile("(?<=" + constraint.getName() + ")(.*?)(?=\\))", Pattern.MULTILINE); Matcher matcher = patternConstraint.matcher(constraint.getSql()); if (matcher.find()) @@ -76,7 +93,11 @@ private String constraintFromOracle(DBConstraint constraint) {//TODO: change } private String constraintFromPostgres(MetaTable table, DBConstraint constraint) {//TODO: change - ConsoleWriter.println("Converting table constraint " + constraint.getName() + " from postgresql to mysql..."); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingConstraint") + .withParams(constraint.getName(), "postgresql", "mysql") + , messageLevel + ); String ddl = constraint.getOptions().get("ddl") .toString() @@ -92,7 +113,11 @@ private String constraintFromPostgres(MetaTable table, DBConstraint constraint) } private String typeFromAnotherDB(DbType dbType, DBTableField field) { - ConsoleWriter.println("Converting table field " + field.getName() + " from " + dbType.toString().toLowerCase() + " to mysql..."); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingField") + .withParams(field.getName(), dbType.toString().toLowerCase(), "mysql") + , messageLevel + ); String result; switch (field.getTypeUniversal()) { case STRING: diff --git a/src/main/java/ru/fusionsoft/dbgit/mysql/converters/ViewConverterMySql.java b/src/main/java/ru/fusionsoft/dbgit/mysql/converters/ViewConverterMySql.java index 3209836..2f4deff 100644 --- a/src/main/java/ru/fusionsoft/dbgit/mysql/converters/ViewConverterMySql.java +++ b/src/main/java/ru/fusionsoft/dbgit/mysql/converters/ViewConverterMySql.java @@ -1,6 +1,7 @@ package ru.fusionsoft.dbgit.mysql.converters; import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.meta.IMetaObject; @@ -17,7 +18,11 @@ public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) thr if (obj instanceof MetaView) { MetaView view = (MetaView) obj; view.setDbType(DbType.MYSQL); - ConsoleWriter.println("Processing view " + view.getName()); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingView") + .withParams(view.getName()) + , messageLevel + ); switch(objDbType) { case POSTGRES: String ddl = view.getSqlObject().getSql(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBAdapterOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBAdapterOracle.java index bf595c5..032af9a 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBAdapterOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBAdapterOracle.java @@ -5,23 +5,18 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; -import java.util.Set; +import org.apache.commons.lang3.exception.ExceptionUtils; import ru.fusionsoft.dbgit.adapters.DBAdapter; import ru.fusionsoft.dbgit.adapters.IDBAdapter; import ru.fusionsoft.dbgit.adapters.IDBAdapterRestoreMetaData; import ru.fusionsoft.dbgit.adapters.IFactoryDBAdapterRestoteMetaData; import ru.fusionsoft.dbgit.adapters.IFactoryDBBackupAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; -import ru.fusionsoft.dbgit.core.DBGitConfig; -import ru.fusionsoft.dbgit.core.DBGitLang; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; +import ru.fusionsoft.dbgit.core.*; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.core.db.FieldType; import ru.fusionsoft.dbgit.data_table.BooleanData; @@ -32,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; @@ -46,28 +43,37 @@ 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; +import ru.fusionsoft.dbgit.meta.TreeMapMetaObject; import ru.fusionsoft.dbgit.oracle.FactoryDBAdapterRestoreOracle; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.LoggerUtil; import org.slf4j.Logger; +import ru.fusionsoft.dbgit.utils.StringProperties; public class DBAdapterOracle extends DBAdapter { - private Logger logger = LoggerUtil.getLogger(this.getClass()); - private FactoryDBAdapterRestoreOracle restoreFactory = new FactoryDBAdapterRestoreOracle(); - private FactoryDbConvertAdapterOracle convertFactory = new FactoryDbConvertAdapterOracle(); - private FactoryDBBackupAdapterOracle backupFactory = new FactoryDBBackupAdapterOracle(); + final private Logger logger = LoggerUtil.getLogger(this.getClass()); + final private FactoryDBAdapterRestoreOracle restoreFactory = new FactoryDBAdapterRestoreOracle(); + final private FactoryDbConvertAdapterOracle convertFactory = new FactoryDbConvertAdapterOracle(); + final private FactoryDBBackupAdapterOracle backupFactory = new FactoryDBBackupAdapterOracle(); + final private static Set reservedWords = new HashSet<>(); - private String s; @Override public IFactoryDBAdapterRestoteMetaData getFactoryRestore() { return restoreFactory; } + @Override + public IFactoryDBBackupAdapter getBackupAdapterFactory() { return backupFactory; } + @Override + public IFactoryDBConvertAdapter getConvertAdapterFactory() { + return convertFactory; + } @Override public void startUpdateDB() { @@ -80,34 +86,131 @@ public void endUpdateDB() { // TODO Auto-generated method stub } - + + @Override + public boolean userHasRightsToGetDdlOfOtherUsers() { + try { + String userName = getConnection().getSchema(); + + if (userName.equalsIgnoreCase("SYS")) + return true; + + PreparedStatement stmt = getConnection().prepareStatement + ("SELECT count(1) cnt FROM DBA_ROLE_PRIVS WHERE GRANTEE = ? and GRANTED_ROLE = 'SELECT_CATALOG_ROLE'"); + stmt.setString(1, userName); + ResultSet resultSet = stmt.executeQuery(); + resultSet.next(); + + if (resultSet.getInt(1) == 0) { + return false; + } else { + return true; + } + } catch (SQLException e) { + logger.error(e.getMessage()); + return false; + } + } + + @Override + public DbType getDbType() { + return DbType.ORACLE; + } + @Override + public String getDbVersion() { + final String query = "SELECT version FROM V$INSTANCE"; + try ( + PreparedStatement stmt = getConnection().prepareStatement(query); + ResultSet resultSet = stmt.executeQuery(); + ) { + + if(!resultSet.next()) throw new ExceptionDBGitRunTime("get db version resultset is empty"); + final String result = resultSet.getString("version"); + + return result; + + } catch (SQLException e) { + throw new ExceptionDBGitRunTime(e); + } + } + @Override + public String getDefaultScheme() throws ExceptionDBGit { + try { + return getConnection().getSchema(); + } catch (SQLException e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "getSchema"); + throw new ExceptionDBGit(msg, e); + } + } + + @Override + public void createSchemaIfNeed(String schemaName) throws ExceptionDBGit { + final String userCountQuery = "select count(*) cnt from all_users where USERNAME = '" + schemaName.toUpperCase() + "'"; + try ( + Statement st = connect.createStatement(); + ResultSet rs = st.executeQuery(userCountQuery); + ) { + + if(!rs.next()) throw new ExceptionDBGitRunTime("get schema count empty resultset"); + if (rs.getInt("cnt") == 0) { + try(StatementLogging stLog = new StatementLogging(connect, getStreamOutputSqlCommand(), isExecSql());){ + + final String configureUserQuery = "ALTER USER \"" + schemaName.toUpperCase() + "\" QUOTA UNLIMITED ON SYSTEM"; + final String createUserQuery = + "create USER \"" + schemaName.toUpperCase() + "\"\r\n" + + "IDENTIFIED BY \"" + schemaName.toUpperCase() + "\"\r\n" + + "DEFAULT TABLESPACE \"SYSTEM\"\r\n" + + "TEMPORARY TABLESPACE \"TEMP\"\r\n" + + "ACCOUNT UNLOCK"; + + stLog.execute(createUserQuery); + stLog.execute(configureUserQuery); + } + } + + } catch (SQLException e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "createSchema"); + throw new ExceptionDBGit(msg, e); + } + + } + @Override + public void createRoleIfNeed(String roleName) throws ExceptionDBGit { + //TODO implement + } + + @Override + public boolean isReservedWord(String word) { + return reservedWords.contains(word.toUpperCase()); + } + @Override public IMapMetaObject loadCustomMetaObjects() { - return null; + return new TreeMapMetaObject(Collections.emptyList()); } @Override public Map getSchemes() { - Map listScheme = new HashMap(); - try { - String query = "SELECT DISTINCT OWNER\n" + - "FROM DBA_OBJECTS WHERE OWNER != 'PUBLIC' AND OWNER != 'SYSTEM'\n" + - "AND OWNER != 'SYS' AND OWNER != 'APPQOSSYS' AND OWNER != 'OUTLN' \n" + - "AND OWNER != 'DIP' AND OWNER != 'DBSNMP' AND OWNER != 'ORACLE_OCM'\n" + - "ORDER BY OWNER"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listScheme = new HashMap(); + final String query = + "SELECT DISTINCT OWNER\n" + + "FROM DBA_OBJECTS WHERE OWNER != 'PUBLIC' AND OWNER != 'SYSTEM'\n" + + "AND OWNER != 'SYS' AND OWNER != 'APPQOSSYS' AND OWNER != 'OUTLN' \n" + + "AND OWNER != 'DIP' AND OWNER != 'DBSNMP' AND OWNER != 'ORACLE_OCM'\n" + + "ORDER BY OWNER"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ - String name = rs.getString("OWNER"); - DBSchema scheme = new DBSchema(name); - rowToProperties(rs, scheme.getOptions()); - listScheme.put(name, scheme); - } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "schemes").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "schemes").toString(), e); + final String name = rs.getString("OWNER"); + final DBSchema scheme = new DBSchema(name, new StringProperties(rs)); + + listScheme.put(name, scheme); + } + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "schemes").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listScheme; @@ -115,788 +218,783 @@ public Map getSchemes() { @Override public Map getTableSpaces() { - Map listTableSpace = new HashMap(); - try { - String query = "SELECT owner,\n" + - " segment_name,\n" + - " partition_name,\n" + - " segment_type,\n" + - " bytes \n" + - " FROM dba_segments \n" + - " WHERE OWNER != 'PUBLIC' AND OWNER != 'SYSTEM'\n" + - "AND OWNER != 'SYS' AND OWNER != 'APPQOSSYS' AND OWNER != 'OUTLN' \n" + - "AND OWNER != 'DIP' AND OWNER != 'DBSNMP' AND OWNER != 'ORACLE_OCM' and segment_name not like 'SYS%'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listTableSpace = new HashMap(); + final String query = + "SELECT owner,\n" + + " segment_name,\n" + + " partition_name,\n" + + " segment_type,\n" + + " bytes \n" + + " FROM dba_segments \n" + + " WHERE OWNER != 'PUBLIC' AND OWNER != 'SYSTEM'\n" + + "AND OWNER != 'SYS' AND OWNER != 'APPQOSSYS' AND OWNER != 'OUTLN' \n" + + "AND OWNER != 'DIP' AND OWNER != 'DBSNMP' AND OWNER != 'ORACLE_OCM' and segment_name not like 'SYS%'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ - String name = rs.getString("segment_name"); - DBTableSpace dbTableSpace = new DBTableSpace(name); - rowToProperties(rs, dbTableSpace.getOptions()); + final String name = rs.getString("segment_name"); + final DBTableSpace dbTableSpace = new DBTableSpace(name, new StringProperties(rs)); listTableSpace.put(name, dbTableSpace); - } - stmt.close(); - }catch(Exception e) { - logger.error(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); + } + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tablespace").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listTableSpace; } @Override public Map getSequences(String schema) { - Map listSequence = new HashMap(); - try { - Connection connect = getConnection(); - //variant 1 from DBA_OBJECTS - /*String query = - "SELECT ROWNUM AS NUM, OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_TYPE, STATUS,\n" + - "(select dbms_metadata.get_ddl('SEQUENCE', O.OBJECT_NAME) AS DDL from dual) AS DDL\n" + - "FROM DBA_OBJECTS O WHERE OBJECT_TYPE = 'SEQUENCE' AND OWNER = :schema";*/ - - //variant 2 from DBA_SEQUENCES - String query = - "SELECT S.SEQUENCE_NAME, (SELECT dbms_metadata.get_ddl('SEQUENCE', S.SEQUENCE_NAME, S.SEQUENCE_OWNER) from dual) AS DDL,\n" + - "order_flag, increment_by, last_number, min_value, max_value, cache_size \n" + - "FROM DBA_SEQUENCES S WHERE S.SEQUENCE_OWNER = '" + schema + "'"; - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listSequence = new HashMap(); + + //variant 1 from DBA_OBJECTS + /*String query = + "SELECT ROWNUM AS NUM, OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_TYPE, STATUS,\n" + + "(select dbms_metadata.get_ddl('SEQUENCE', O.OBJECT_NAME) AS DDL from dual) AS DDL\n" + + "FROM DBA_OBJECTS O WHERE OBJECT_TYPE = 'SEQUENCE' AND OWNER = :schema";*/ + + //variant 2 from DBA_SEQUENCES + final String query = + "SELECT S.SEQUENCE_NAME, (SELECT dbms_metadata.get_ddl('SEQUENCE', S.SEQUENCE_NAME, S.SEQUENCE_OWNER) from dual) AS DDL,\n" + + "order_flag, increment_by, last_number, min_value, max_value, cache_size \n" + + "FROM DBA_SEQUENCES S WHERE S.SEQUENCE_OWNER = '" + schema + "'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { while(rs.next()){ - String nameSeq = rs.getString("SEQUENCE_NAME"); - DBSequence sequence = new DBSequence(); - sequence.setName(nameSeq); - sequence.setSchema(schema); - sequence.setValue(0L); - rowToProperties(rs, sequence.getOptions()); + //TODO find real sequence value + final long valueSeq = 0L; + final String nameSeq = rs.getString("SEQUENCE_NAME"); + final String ownerSeq = ""; + final DBSequence sequence = new DBSequence(nameSeq, new StringProperties(rs), schema, ownerSeq, Collections.emptySet(), valueSeq); listSequence.put(nameSeq, sequence); } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "sequences").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "sequences").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "seq").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listSequence; } @Override public DBSequence getSequence(String schema, String name) { - try { - Connection connect = getConnection(); - String query = - "SELECT S.SEQUENCE_NAME, (SELECT dbms_metadata.get_ddl('SEQUENCE', S.SEQUENCE_NAME, S.SEQUENCE_OWNER) from dual) AS DDL, \n" + - "order_flag, increment_by, last_number, min_value, max_value, cache_size \n" + - "FROM DBA_SEQUENCES S WHERE S.SEQUENCE_OWNER = '" + schema + "' AND S.SEQUENCE_NAME = '" + name + "'"; - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - DBSequence sequence = null; - while (rs.next()) { - String nameSeq = rs.getString("SEQUENCE_NAME"); - sequence = new DBSequence(); - sequence.setName(nameSeq); - sequence.setSchema(schema); - sequence.setValue(0L); - rowToProperties(rs, sequence.getOptions()); + final String query = + "SELECT S.SEQUENCE_NAME, (SELECT dbms_metadata.get_ddl('SEQUENCE', S.SEQUENCE_NAME, S.SEQUENCE_OWNER) from dual) AS DDL, \n" + + "order_flag, increment_by, last_number, min_value, max_value, cache_size \n" + + "FROM DBA_SEQUENCES S WHERE S.SEQUENCE_OWNER = '" + schema + "' AND S.SEQUENCE_NAME = '" + name + "'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + if (rs.next()) { + //TODO find real sequence value + final long valueSeq = 0L; + final String nameSeq = rs.getString("SEQUENCE_NAME"); + final String ownerSeq = ""; + return new DBSequence(nameSeq, new StringProperties(rs), schema, ownerSeq, Collections.emptySet(), valueSeq); + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - stmt.close(); - return sequence; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "sequences").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "sequences").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "sequence").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public Map getTables(String schema) { - Map listTable = new HashMap(); - try { - String query = "SELECT T.TABLE_NAME, T.OWNER, (SELECT dbms_metadata.get_ddl('TABLE', T.TABLE_NAME, T.OWNER) from dual) AS DDL\n" + - "FROM DBA_TABLES T WHERE upper(OWNER) = upper('" + schema + "') and nested = 'NO' and (iot_type <> 'IOT_OVERFLOW' or iot_type is null)"; - Connection connect = getConnection(); - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - + final Map listTable = new HashMap(); + final String query = + "SELECT T.TABLE_NAME, T.OWNER, (SELECT dbms_metadata.get_ddl('TABLE', T.TABLE_NAME, T.OWNER) from dual) AS DDL\n" + + "FROM DBA_TABLES T WHERE upper(OWNER) = upper('" + schema + "') and nested = 'NO' and (iot_type <> 'IOT_OVERFLOW' or iot_type is null)"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { while(rs.next()){ - String nameTable = rs.getString("TABLE_NAME"); - DBTable table = new DBTable(nameTable); - table.setSchema(schema); - rowToProperties(rs, table.getOptions()); + //TODO retrieve table comment + //TODO retrieve table owner + final String nameTable = rs.getString("TABLE_NAME"); + final String ownerTable = ""; + final String commentTable = ""; + final StringProperties options = new StringProperties(rs); + final Set dependencies = rs.getArray("dependencies") != null + ? new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())) + : Collections.emptySet(); + + final DBTable table = new DBTable(nameTable, options, schema, ownerTable, dependencies, commentTable); listTable.put(nameTable, table); } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listTable; } @Override public DBTable getTable(String schema, String name) { - try { - String query = "SELECT T.TABLE_NAME, T.OWNER, (SELECT dbms_metadata.get_ddl('TABLE', T.TABLE_NAME, T.OWNER) from dual) AS DDL\n" + - "FROM DBA_TABLES T WHERE upper(T.OWNER) = upper('" + schema + "') AND upper(T.TABLE_NAME) = upper('" + name + "')"; - Connection connect = getConnection(); - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - DBTable table = null; - - while(rs.next()) { - String nameTable = rs.getString("TABLE_NAME"); - table = new DBTable(nameTable); - table.setSchema(schema); - rowToProperties(rs, table.getOptions()); + final String query = + "SELECT T.TABLE_NAME, T.OWNER, (SELECT dbms_metadata.get_ddl('TABLE', T.TABLE_NAME, T.OWNER) from dual) AS DDL\n" + + "FROM DBA_TABLES T WHERE upper(T.OWNER) = upper('" + schema + "') AND upper(T.TABLE_NAME) = upper('" + name + "')"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + + if (rs.next()) { + //TODO retrieve table comment + //TODO retrieve table owner + final String nameTable = rs.getString("TABLE_NAME"); + final String ownerTable = ""; + final String commentTable = ""; + final StringProperties options = new StringProperties(rs); + final Set dependencies = rs.getArray("dependencies") != null + ? new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())) + : Collections.emptySet(); + + return new DBTable(nameTable, options, schema, ownerTable, dependencies, commentTable); + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - - stmt.close(); - return table; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + } @Override public Map getTableFields(String schema, String nameTable) { - try { - Map listField = new HashMap(); - - String query1 = - "SELECT column_name FROM all_constraints cons, all_cons_columns cols\n"+ - "WHERE upper(cols.table_name) = upper('" + nameTable + "')\n"+ - "AND cons.constraint_type = 'P'\n" + - "AND cons.constraint_name = cols.constraint_name\n" + - "AND cons.owner = cols.owner"; - Connection connect = getConnection(); - - Statement stmt = connect.createStatement(); - ResultSet rs1 = stmt.executeQuery(query1); - - String s = ""; - - while (rs1.next()) - s = rs1.getString("COLUMN_NAME").toLowerCase(); - - String query = - "SELECT case \r\n" + - " when lower(data_type) in ('number', 'numeric', 'dec', 'decimal', 'pls_integer') then 'number'\r\n" + - " when lower(data_type) in ('varchar2', 'varchar', 'char', 'nchar', 'nvarchar2') then 'string'\r\n" + - " when substr(lower(data_type), 1, instr(data_type, '(') - 1) in ('date', 'timestamp') then 'date'\r\n" + - " when lower(data_type) in ('date', 'timestamp') then 'date'\r\n" + - " when lower(data_type) in ('clob') then 'text'\r\n" + - " when lower(data_type) in ('blob') then 'binary'" + - " else 'native'\r\n" + - " end type, " + - " case when lower(data_type) in ('char', 'nchar') then 1 else 0 end fixed, " + - " ROWNUM AS NUM, TC.* FROM DBA_TAB_COLS TC \n" + - "WHERE lower(table_name) = lower('" + nameTable + "') AND lower(OWNER) = lower('" + schema + "') ORDER BY column_id"; - - ResultSet rs = stmt.executeQuery(query); - while(rs.next()){ - DBTableField field = new DBTableField(); - field.setName(rs.getString("COLUMN_NAME").toLowerCase()); - if (rs.getString("COLUMN_NAME").toLowerCase().equals(s)) { - field.setIsPrimaryKey(true); - } - String typeSQL = getFieldType(rs); - field.setTypeSQL(typeSQL); - field.setIsNullable( !typeSQL.toLowerCase().contains("not null")); - field.setTypeUniversal(FieldType.fromString(rs.getString("TYPE").toUpperCase())); - field.setLength(rs.getInt("DATA_LENGTH")); - field.setScale(rs.getInt("DATA_SCALE")); - field.setPrecision(rs.getInt("DATA_PRECISION")); - field.setFixed(rs.getBoolean("fixed")); - field.setOrder(rs.getInt("column_id")); + final Map listField = new HashMap(); + + final String pkNameQuery = + "SELECT column_name FROM all_constraints cons, all_cons_columns cols\n"+ + "WHERE upper(cols.table_name) = upper('" + nameTable + "')\n"+ + "AND cons.constraint_type = 'P'\n" + + "AND cons.constraint_name = cols.constraint_name\n" + + "AND cons.owner = cols.owner"; + + final String query = + "SELECT " + + " case \r\n" + + " when lower(data_type) in ('number', 'numeric', 'dec', 'decimal', 'pls_integer') then 'number'\r\n" + + " when lower(data_type) in ('varchar2', 'varchar', 'char', 'nchar', 'nvarchar2') then 'string'\r\n" + + " when substr(lower(data_type), 1, instr(data_type, '(') - 1) in ('date', 'timestamp') then 'date'\r\n" + + " when lower(data_type) in ('date', 'timestamp') then 'date'\r\n" + + " when lower(data_type) in ('clob') then 'text'\r\n" + + " when lower(data_type) in ('blob') then 'binary'" + + " else 'native'\r\n" + + " end type, " + + " case " + + " when lower(data_type) in ('char', 'nchar') then 1 else 0 " + + " end fixed, " + + " ROWNUM AS NUM, " + + " TC.* \n" + + " DTC.COMMENTS \n" + + "FROM DBA_TAB_COLS TC \n" + + "LEFT OUTER JOIN dba_tables T " + + " ON T.TABLE_NAME = TC.TABLE_NAME " + + " AND T.COLUMN_NAME = TC.COLUMN_NAME \n" + + " AND T.OWNER = TC.OWNER \n" + + //So I checked the documentation it turns out Oracle 10g added a column called DROPPED to the USER_/ALL_/DBA_TABLES views. + ( (getDbVersionNumber() >= 10) ? + " AND T.DROPPED = 'NO' \n" : "" ) + + "LEFT OUTER JOIN dba_tab_comment TCOM " + + " ON TCOM.OWNER = T.OWNER " + + " AND TCOM.TABLE_NAME = T.TABLE_NAME " + + " AND TCOM.COLUMN_NAME = TC.COLUMN_NAME " + + "WHERE lower(table_name) = lower('" + nameTable + "') AND lower(OWNER) = lower('" + schema + "') ORDER BY column_id"; + + try ( + Statement stmt = getConnection().createStatement(); + ResultSet pkRs = stmt.executeQuery(pkNameQuery); + ResultSet fieldsRs = stmt.executeQuery(query); + ){ + + final Set pkColumnNames = new HashSet<>(); + while (pkRs.next()) { pkColumnNames.add(pkRs.getString("COLUMN_NAME").toLowerCase()); } + while(fieldsRs.next()){ + //TODO make restore 'description', 'column default' + final String columnName = fieldsRs.getString("COLUMN_NAME").toLowerCase(); + final String columnDesc = fieldsRs.getString("COMMENTS"); + final Long columnDefault = fieldsRs.getLong("DATA_DEFAULT"); + final String typeSQL = getFieldType(fieldsRs); + final FieldType typeUniversal = FieldType.fromString(fieldsRs.getString("TYPE").toUpperCase()); + final int order = fieldsRs.getInt("column_id"); + final boolean isPrimaryKey = pkColumnNames.contains(columnName); + final boolean isNullable = !typeSQL.toLowerCase().contains("not null"); + final boolean fixed = fieldsRs.getBoolean("fixed"); + final int dataLength = fieldsRs.getInt("DATA_LENGTH"); + final int dataScale = fieldsRs.getInt("DATA_SCALE"); + final int dataPrecision = fieldsRs.getInt("DATA_PRECISION"); + + + final DBTableField field = new DBTableField( + columnName, + columnDesc != null ? columnDesc : "", + isPrimaryKey, + isNullable, + typeSQL, typeUniversal, order, + columnDefault != null ? String.valueOf(columnDefault) : "", + dataLength, dataScale, dataPrecision, fixed + ); + + listField.put(field.getName(), field); } - - stmt.close(); - - return listField; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); - } + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); + } + + return listField; } - protected String getFieldType(ResultSet rs) { - try { - StringBuilder type = new StringBuilder(); - type.append(rs.getString("DATA_TYPE")); - - Integer max_length = rs.getInt("CHAR_LENGTH"); - if (!rs.wasNull() && !rs.getString("DATA_TYPE").contains("(")) { - type.append("("+max_length.toString()+")"); - } - - if (rs.getString("NULLABLE").equals("N")){ - type.append(" NOT NULL"); - } - - return type.toString(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); - } + protected String getFieldType(ResultSet rs) throws SQLException { + final StringBuilder type = new StringBuilder(); + final Integer max_length = rs.getInt("CHAR_LENGTH"); + final String data_type = rs.getString("DATA_TYPE"); + + type.append(data_type); + + if (!rs.wasNull() && !data_type.contains("(")) { + type.append("("+max_length.toString()+")"); + } + + if (rs.getString("NULLABLE").equals("N")){ + type.append(" NOT NULL"); + } + + return type.toString(); } @Override public Map getIndexes(String schema, String nameTable) { - Map indexes = new HashMap<>(); - try { - String query = "SELECT ind.index_name, (select dbms_metadata.get_ddl('INDEX', ind.INDEX_NAME, owner) AS DDL from dual) AS DDL\n" + - "FROM all_indexes ind\n" + - "WHERE upper(table_name) = upper('" + nameTable + "') AND upper(owner) = upper('" + schema + "')"; - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map indexes = new HashMap<>(); + final String query = + "SELECT ind.index_name, (select dbms_metadata.get_ddl('INDEX', ind.INDEX_NAME, owner) AS DDL from dual) AS DDL\n" + + "FROM all_indexes ind\n" + + "WHERE upper(table_name) = upper('" + nameTable + "') AND upper(owner) = upper('" + schema + "')"; + + try (Statement stmt = connect.createStatement(); ResultSet rs = stmt.executeQuery(query);){ while(rs.next()){ - DBIndex index = new DBIndex(); - index.setName(rs.getString("INDEX_NAME")); - index.setSchema(schema); - rowToProperties(rs, index.getOptions()); + //TODO find real owner + final String name = rs.getString("INDEX_NAME"); + final String sql = rs.getString("DDL"); + final DBIndex index = new DBIndex(name, new StringProperties(rs), schema, schema, Collections.emptySet(), sql); indexes.put(index.getName(), index); } - stmt.close(); - - return indexes; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "indexes").toString()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "indexes").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "indexes").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + + return indexes; } @Override public Map getConstraints(String schema, String nameTable) { - Map constraints = new HashMap<>(); - try { - String query = "SELECT cons.constraint_type, cons.CONSTRAINT_NAME, (select dbms_metadata.get_ddl('CONSTRAINT', cons.constraint_name, owner) AS DDL from dual) AS DDL\n" + - "FROM all_constraints cons\n" + - "WHERE upper(owner) = upper('" + schema + "') and upper(table_name) = upper('" + nameTable + "') and constraint_name not like 'SYS%' and cons.constraint_type = 'P'"; + final Map constraints = new HashMap<>(); + + final String query = + "SELECT cons.constraint_type, cons.CONSTRAINT_NAME, (select dbms_metadata.get_ddl('CONSTRAINT', cons.constraint_name, owner) AS DDL from dual) AS DDL\n" + + "FROM all_constraints cons\n" + + "WHERE upper(owner) = upper('" + schema + "') and upper(table_name) = upper('" + nameTable + "') and constraint_name not like 'SYS%' and cons.constraint_type = 'P'"; + + try (Statement stmt = connect.createStatement(); ResultSet rs = stmt.executeQuery(query);) { - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - while(rs.next()){ - DBConstraint con = new DBConstraint(); - con.setName(rs.getString("CONSTRAINT_NAME")); - //This is DDL? - con.setConstraintType(rs.getString("CONSTRAINT_TYPE")); - con.setSchema(schema); - rowToProperties(rs, con.getOptions()); + //TODO find real owner + final String name = rs.getString("CONSTRAINT_NAME"); + final String sql = rs.getString("DDL"); + final String type = rs.getString("CONSTRAINT_TYPE"); + final String owner = schema; + final StringProperties options = new StringProperties(rs); + + final DBConstraint con = new DBConstraint(name, options, schema, owner, Collections.emptySet(), sql, type); constraints.put(con.getName(), con); } - stmt.close(); - - return constraints; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "constraints").toString()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "constraints").toString(), e); + + } + catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "constraints").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + + return constraints; } @Override public Map getViews(String schema) { - Map listView = new HashMap(); - try { - String query = "SELECT f.owner, f.object_name, (select dbms_metadata.get_ddl('VIEW', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + - "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'VIEW'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listView = new HashMap(); + final String query = + "SELECT f.owner, f.object_name, (select dbms_metadata.get_ddl('VIEW', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + + "FROM all_objects f " + + "WHERE f.owner = '" + schema + "' and f.object_type = 'VIEW'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + while(rs.next()){ - DBView view = new DBView(rs.getString("OBJECT_NAME")); - view.setSchema(rs.getString("OWNER")); - view.setOwner(rs.getString("OWNER")); - rowToProperties(rs, view.getOptions()); - listView.put(rs.getString("OBJECT_NAME"), view); + final String name = rs.getString("OBJECT_NAME"); + final String owner = rs.getString("OWNER"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + final Set dependencies = Collections.emptySet(); + + final DBView view = new DBView(name, options, schema, owner, dependencies, sql); + listView.put(name, view); } - stmt.close(); - return listView; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "views") + ": "+ e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "views") + ": " + e.getMessage()); + + } catch(Exception e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "views"); + throw new ExceptionDBGitRunTime(msg, e); } + + return listView; } @Override public DBView getView(String schema, String name) { - DBView view = new DBView(name); - view.setSchema(schema); - try { - String query = "SELECT f.owner, f.object_name, (select dbms_metadata.get_ddl('VIEW', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + - "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'VIEW' and f.object_name = '" + name + "'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - view.setOwner(schema); - - while (rs.next()) { - view.setOwner(rs.getString("OWNER")); - rowToProperties(rs, view.getOptions()); - } - stmt.close(); - return view; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "views").toString() + ": "+ e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "views").toString() + ": "+ e.getMessage()); + + final String query = + "SELECT f.owner, f.object_name, (select dbms_metadata.get_ddl('VIEW', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + + "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'VIEW' and f.object_name = '" + name + "'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); ){ + + if (!rs.next()) throw new ExceptionDBGitObjectNotFound("view is not found in db"); + + final String owner = rs.getString("owner"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + return new DBView(name, options, schema, owner, Collections.emptySet(), sql); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "views").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + } public Map getTriggers(String schema) { - Map listTrigger = new HashMap(); - try { - String query = "SELECT tr.owner, tr.trigger_name, tr.trigger_type, tr.table_name," + - " (select dbms_metadata.get_ddl('TRIGGER', tr.trigger_name, tr.owner) AS DDL from dual) AS DDL\n" + - "FROM all_triggers tr\n" + - "WHERE owner = '"+ schema +"'"; - - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - - ResultSet rs = stmt.executeQuery(query); + + final Map listTrigger = new HashMap(); + final String query = + "SELECT tr.owner, tr.trigger_name, tr.trigger_type, tr.table_name," + + " (select dbms_metadata.get_ddl('TRIGGER', tr.trigger_name, tr.owner) AS DDL from dual) AS DDL\n" + + "FROM all_triggers tr\n" + + "WHERE owner = '"+ schema +"'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + while(rs.next()){ - String name = rs.getString("TRIGGER_NAME"); - String sql = rs.getString("DDL"); - DBTrigger trigger = new DBTrigger(name); - trigger.setSchema(schema); + //TODO find real owner //what means owner? oracle/postgres or owner like database user/schema - trigger.setOwner("oracle"); - rowToProperties(rs, trigger.getOptions()); + final String owner = rs.getString("owner"); + final String name = rs.getString("TRIGGER_NAME"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + + final DBTrigger trigger = new DBTrigger(name, options, schema, owner, Collections.emptySet(), sql); listTrigger.put(name, trigger); } - stmt.close(); - return listTrigger; - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "triggers").toString(), e); + + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "triggers").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + + return listTrigger; } public DBTrigger getTrigger(String schema, String name) { - DBTrigger trigger = null; - try { - String query = "SELECT tr.owner, tr.trigger_name, tr.trigger_type, tr.table_name, (select dbms_metadata.get_ddl('TRIGGER', tr.trigger_name, tr.owner) AS DDL from dual) AS DDL\n" + - "FROM all_triggers tr\n" + - "WHERE owner = '" + schema + "' and trigger_name = '" + name + "'"; - - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - while(rs.next()){ - trigger = new DBTrigger(name); - trigger.setSchema(schema); - //what means owner? oracle/postgres or owner like database user/schema - trigger.setOwner("oracle"); - rowToProperties(rs, trigger.getOptions()); - } - stmt.close(); - return trigger; - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "triggers").toString(), e); + final String query = + "SELECT tr.owner, tr.trigger_name, tr.trigger_type, tr.table_name, (select dbms_metadata.get_ddl('TRIGGER', tr.trigger_name, tr.owner) AS DDL from dual) AS DDL\n" + + "FROM all_triggers tr\n" + + "WHERE owner = '" + schema + "' and trigger_name = '" + name + "'"; + + try (Statement stmt = connect.createStatement(); ResultSet rs = stmt.executeQuery(query);) { + + if(!rs.next()) throw new ExceptionDBGitObjectNotFound("trigger is not found in database"); + + final String owner = rs.getString("owner"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + + return new DBTrigger(name, options, schema, owner, Collections.emptySet(), sql); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "triggers").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + } @Override public Map getPackages(String schema) { - Map listPackage = new HashMap(); - try { - String query = "SELECT f.owner, f.object_name, (select dbms_metadata.get_ddl('PACKAGE', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + - "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'PACKAGE'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listPackage = new HashMap(); + final String query = + "SELECT f.owner, f.object_name, (select dbms_metadata.get_ddl('PACKAGE', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + + "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'PACKAGE'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); ){ + while(rs.next()){ - String name = rs.getString("OBJECT_NAME"); - String owner = rs.getString("OWNER"); + final String name = rs.getString("OBJECT_NAME"); + final String owner = rs.getString("OWNER"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + //String args = rs.getString("arguments"); - DBPackage pack = new DBPackage(name); - pack.setSchema(schema); - pack.setOwner(owner); - rowToProperties(rs,pack.getOptions()); //pack.setArguments(args); + + final DBPackage pack = new DBPackage(name, options, schema, owner, Collections.emptySet(), sql); listPackage.put(name, pack); } - stmt.close(); - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "pkg").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "pkg").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listPackage; } @Override public DBPackage getPackage(String schema, String name) { - try { - String query = "SELECT f.owner, f.object_name, (select dbms_metadata.get_ddl('PACKAGE', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + - "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'PACKAGE' and f.object_name = '" + name + "'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - DBPackage pack = null; - while (rs.next()) { - pack = new DBPackage(name); - String owner = rs.getString("OWNER"); - //String args = rs.getString("arguments"); - pack.setSchema(schema); - pack.setOwner(owner); - //pack.setArguments(args); - rowToProperties(rs,pack.getOptions()); - } - stmt.close(); - - return pack; - - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "views").toString(), e); + final String query = + "SELECT f.owner, f.object_name, (select dbms_metadata.get_ddl('PACKAGE', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + + "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'PACKAGE' and f.object_name = '" + name + "'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + + if (!rs.next()) throw new ExceptionDBGitObjectNotFound("package is not found in db"); + + final String owner = rs.getString("OWNER"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + + //String args = rs.getString("arguments"); + //pack.setArguments(args); + return new DBPackage(name, options, schema, owner, Collections.emptySet(), sql); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "views").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + } @Override public Map getProcedures(String schema) { - Map listProcedure = new HashMap(); - try { - String query = "SELECT f.owner, f.object_name, (select listagg(DATA_TYPE, ' ' ) within group (order by DATA_TYPE) from ALL_ARGUMENTS " + - "WHERE object_name = f.OBJECT_NAME AND owner = f.owner) arguments, (select dbms_metadata.get_ddl('PROCEDURE', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + - "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'PROCEDURE'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listProcedure = new HashMap(); + final String query = + "SELECT f.owner, f.object_name, (select listagg(DATA_TYPE, ' ' ) within group (order by DATA_TYPE) from ALL_ARGUMENTS " + + "WHERE object_name = f.OBJECT_NAME AND owner = f.owner) arguments, (select dbms_metadata.get_ddl('PROCEDURE', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + + "FROM all_objects f WHERE f.owner = '" + schema + "' " + + "AND f.object_type = 'PROCEDURE'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + while(rs.next()){ - String name = rs.getString("OBJECT_NAME"); - String owner = rs.getString("OWNER"); + final String name = rs.getString("OBJECT_NAME"); + final String owner = rs.getString("OWNER"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + //String args = rs.getString("arguments"); - DBProcedure proc = new DBProcedure(name); - proc.setSchema(schema); - proc.setOwner(owner); - proc.setName(name); - rowToProperties(rs,proc.getOptions()); //proc.setArguments(args); + final DBProcedure proc = new DBProcedure(name, options, schema, owner, Collections.emptySet(), sql); listProcedure.put(name, proc); } - stmt.close(); - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "prc").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "prc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listProcedure; } @Override public DBProcedure getProcedure(String schema, String name) { - try { - String query = "SELECT f.owner, f.object_name, (select listagg(DATA_TYPE, ' ' ) within group (order by DATA_TYPE) from ALL_ARGUMENTS " + - "WHERE object_name = f.OBJECT_NAME AND owner = f.owner) arguments, (select dbms_metadata.get_ddl('PROCEDURE', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + - "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'PROCEDURE' and f.object_name = '" + name + "'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - DBProcedure proc = null; - - while (rs.next()) { - proc = new DBProcedure(rs.getString("OBJECT_NAME")); - String owner = rs.getString("OWNER"); - //String args = rs.getString("arguments"); - proc.setSchema(schema); - proc.setOwner(owner); - //proc.setArguments(args); - rowToProperties(rs,proc.getOptions()); - } - stmt.close(); - - return proc; - - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "prc").toString(), e); + + final String query = + "SELECT f.owner, f.object_name, (select listagg(DATA_TYPE, ' ' ) within group (order by DATA_TYPE) from ALL_ARGUMENTS " + + "WHERE object_name = f.OBJECT_NAME AND owner = f.owner) arguments, (select dbms_metadata.get_ddl('PROCEDURE', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + + "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'PROCEDURE' and f.object_name = '" + name + "'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + + if (!rs.next()) throw new ExceptionDBGitObjectNotFound("procedure is not found in database"); + + final String objName = rs.getString("OBJECT_NAME"); + final String owner = rs.getString("OWNER"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + + return new DBProcedure(name, options, schema, owner, Collections.emptySet(), sql); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "prc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + } @Override public Map getFunctions(String schema) { - Map listFunction = new HashMap(); - try { - String query = "SELECT f.owner, f.object_name, (select listagg(DATA_TYPE, ' ' ) within group (order by DATA_TYPE) from ALL_ARGUMENTS \r\n" + - "WHERE object_name = f.OBJECT_NAME AND owner = f.owner) arguments, (select dbms_metadata.get_ddl('FUNCTION', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + - "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'FUNCTION'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listFunction = new HashMap(); + final String query = + "SELECT f.owner, f.object_name, (select listagg(DATA_TYPE, ' ' ) within group (order by DATA_TYPE) from ALL_ARGUMENTS \r\n" + + "WHERE object_name = f.OBJECT_NAME AND owner = f.owner) arguments, (select dbms_metadata.get_ddl('FUNCTION', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + + "FROM all_objects f WHERE f.owner = '" + schema + "' and f.object_type = 'FUNCTION'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { while(rs.next()){ - String name = rs.getString("OBJECT_NAME"); - String sql = rs.getString("DDL"); - String owner = rs.getString("OWNER"); + final String name = rs.getString("OBJECT_NAME"); + final String sql = rs.getString("DDL"); + final String owner = rs.getString("OWNER"); + final StringProperties options = new StringProperties(rs); + //String args = rs.getString("arguments"); - DBFunction func = new DBFunction(name); - func.setSchema(schema); - func.setOwner(owner); - rowToProperties(rs,func.getOptions()); //func.setArguments(args); + final DBFunction func = new DBFunction(name, options, schema, owner, Collections.emptySet(), sql); listFunction.put(name, func); } - stmt.close(); - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "fnc").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "fnc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listFunction; } @Override public DBFunction getFunction(String schema, String name) { - try { - String query = "SELECT f.owner, f.object_name, (select listagg(DATA_TYPE, ' ' ) within group (order by DATA_TYPE) from ALL_ARGUMENTS " + - "WHERE object_name = f.OBJECT_NAME AND owner = f.owner) arguments, (select dbms_metadata.get_ddl('FUNCTION', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + - "FROM all_objects f WHERE f.owner = '" + schema +"' and " + - "f.object_type = 'FUNCTION' and f.object_name = '" + name +"'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - DBFunction func = null; - - while (rs.next()) { - func = new DBFunction(rs.getString("OBJECT_NAME")); - String owner = rs.getString("OWNER"); - //String args = rs.getString("arguments"); - func.setSchema(schema); - func.setOwner(owner); - //func.setArguments(args); - rowToProperties(rs,func.getOptions()); - } - stmt.close(); - - return func; - - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "fnc").toString(), e); + + final String query = + "SELECT f.owner, f.object_name, (select listagg(DATA_TYPE, ' ' ) within group (order by DATA_TYPE) from ALL_ARGUMENTS " + + "WHERE object_name = f.OBJECT_NAME AND owner = f.owner) arguments, (select dbms_metadata.get_ddl('FUNCTION', f.object_name, f.owner) AS DDL from dual) AS DDL \n" + + "FROM all_objects f WHERE f.owner = '" + schema +"' and " + + "f.object_type = 'FUNCTION' and f.object_name = '" + name +"'"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + + if (!rs.next()) throw new ExceptionDBGitObjectNotFound("function is not found in database"); + + final String objName = rs.getString("OBJECT_NAME"); + final String owner = rs.getString("OWNER"); + final String sql = rs.getString("DDL"); + final StringProperties options = new StringProperties(rs); + + + //String args = rs.getString("arguments"); + //func.setArguments(args); + return new DBFunction(objName, options, schema, owner, Collections.emptySet(), sql); + + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "fnc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + } @Override public DBTableData getTableDataPortion(String schema, String nameTable, int portionIndex, int tryNumber) { - DBTableData data = new DBTableData(); - + + final int portionSize = DBGitConfig.getInstance().getInteger("core", "PORTION_SIZE", DBGitConfig.getInstance().getIntegerGlobal("core", "PORTION_SIZE", 1000)); + final int begin = 1 + portionSize*portionIndex; + final int end = portionSize + portionSize*portionIndex; + + final String dataQuery = + "SELECT * FROM (" + + " SELECT f.*, ROW_NUMBER() OVER (ORDER BY rowid) DBGIT_ROW_NUM " + + " FROM " + schema + "." + nameTable + " f" + + ") " + + "WHERE DBGIT_ROW_NUM BETWEEN " + begin + " and " + end; + try { - int portionSize = DBGitConfig.getInstance().getInteger("core", "PORTION_SIZE", DBGitConfig.getInstance().getIntegerGlobal("core", "PORTION_SIZE", 1000)); - - int begin = 1 + portionSize*portionIndex; - int end = portionSize + portionSize*portionIndex; - - Statement st = getConnection().createStatement(); - ResultSet rs = st.executeQuery(" SELECT * FROM \r\n" + - " (SELECT f.*, ROW_NUMBER() OVER (ORDER BY rowid) DBGIT_ROW_NUM FROM " + schema + "." + nameTable + " f)\r\n" + - " WHERE DBGIT_ROW_NUM BETWEEN " + begin + " and " + end); - data.setResultSet(rs); - return data; + + return new DBTableData(getConnection(), dataQuery); + } catch(Exception e) { - ConsoleWriter.println("Connection lost!"); + + final int maxTriesCount = DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000)); + final int tryDelay = DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000)); + + ConsoleWriter.println(e.getLocalizedMessage(), messageLevel); + ConsoleWriter.detailsPrintln(ExceptionUtils.getStackTrace(e), messageLevel); logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - try { - if (tryNumber <= DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000))) { - try { - TimeUnit.SECONDS.sleep(DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000))); - } catch (InterruptedException e1) { - throw new ExceptionDBGitRunTime(e1.getMessage()); - } - ConsoleWriter.println("Error while getting portion of data, try " + tryNumber); - return getTableDataPortion(schema, nameTable, portionIndex, tryNumber++); + if (tryNumber <= maxTriesCount) { + + final String waitMessage = DBGitLang.getInstance() + .getValue("errors", "dataTable", "wait") + .withParams(String.valueOf(tryDelay)); + + final String tryAgainMessage = DBGitLang.getInstance() + .getValue("errors", "dataTable", "tryAgain") + .withParams(String.valueOf(tryNumber)); + + ConsoleWriter.println(waitMessage, messageLevel); + try { TimeUnit.SECONDS.sleep(tryDelay); } catch (InterruptedException e1) { + throw new ExceptionDBGitRunTime(e1.getMessage()); } - } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - try { - getConnection().rollback(); - } catch (Exception e2) { - logger.error(lang.getValue("errors", "adapter", "rollback").toString(), e2); + ConsoleWriter.println(tryAgainMessage, messageLevel); + return getTableDataPortion(schema, nameTable, portionIndex, tryNumber++); + + } else { + final String msg = DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); } - throw new ExceptionDBGitRunTime(e.getMessage()); } } @Override public DBTableData getTableData(String schema, String nameTable) { - String tableName = schema + "." + nameTable; + final String tableName = schema + "." + nameTable; + final Boolean isFetchLimited = DBGitConfig.getInstance().getBoolean("core", "LIMIT_FETCH", DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true)); + final int maxRowsCount = DBGitConfig.getInstance().getInteger("core", "MAX_ROW_COUNT_FETCH", DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH)); + final String dataQuery = "select * from " + tableName; try { - DBTableData data = new DBTableData(); - - int maxRowsCount = DBGitConfig.getInstance().getInteger("core", "MAX_ROW_COUNT_FETCH", DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH)); - - if (DBGitConfig.getInstance().getBoolean("core", "LIMIT_FETCH", DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true))) { - Statement st = getConnection().createStatement(); - String query = "select COALESCE(count(*), 0) row_count from ( select 1 from "+ - tableName+" where ROWNUM <= " + (maxRowsCount + 1) + " ) tbl"; - ResultSet rs = st.executeQuery(query); - rs.next(); - if (rs.getInt("row_count") > maxRowsCount) { - data.setErrorFlag(DBTableData.ERROR_LIMIT_ROWS); - return data; + + if (isFetchLimited) { + final String rowsCountQuery = + "select COALESCE(count(*), 0) row_count " + + "from ( " + + " select 1 " + + " from " + tableName+ " " + + " where ROWNUM <= " + (maxRowsCount + 1) + " " + + ") tbl"; + try(Statement st = getConnection().createStatement(); ResultSet rs = st.executeQuery(rowsCountQuery);){ + + if(!rs.next()) throw new ExceptionDBGitRunTime("empty rows count resultset"); + + if (rs.getInt("row_count") > maxRowsCount) { + return new DBTableData(DBTableData.ERROR_LIMIT_ROWS); + } + } - } - Statement st = getConnection().createStatement(); - ResultSet rs = st.executeQuery("select * from "+tableName); - data.setResultSet(rs); - return data; - - } catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - try { - getConnection().rollback(); - } catch (Exception e2) { - logger.error(lang.getValue("errors", "adapter", "rollback").toString(), e2); } - throw new ExceptionDBGitRunTime(e.getMessage()); + + return new DBTableData(getConnection(), dataQuery); + + } catch(Exception e) { + final String msg = DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } -/* - @Override - public DBTableRow getTableRow(String schema, String nameTable, Object id) { - // TODO Auto-generated method stub - return null; - } -*/ + @Override public Map getUsers() { - Map listUser = new HashMap(); - try { - String query = "SELECT USERNAME FROM DBA_USERS WHERE USERNAME != 'PUBLIC' AND USERNAME != 'SYSTEM'\n" + - "AND USERNAME != 'SYS' AND USERNAME != 'APPQOSSYS' AND USERNAME != 'OUTLN' \n" + - "AND USERNAME != 'DIP' AND USERNAME != 'DBSNMP' AND USERNAME != 'ORACLE_OCM' ORDER BY USERNAME"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + final Map listUser = new HashMap(); + final String query = + "SELECT USERNAME FROM DBA_USERS WHERE USERNAME != 'PUBLIC' AND USERNAME != 'SYSTEM'\n" + + "AND USERNAME != 'SYS' AND USERNAME != 'APPQOSSYS' AND USERNAME != 'OUTLN' \n" + + "AND USERNAME != 'DIP' AND USERNAME != 'DBSNMP' AND USERNAME != 'ORACLE_OCM' ORDER BY USERNAME"; + + try ( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ){ + while(rs.next()){ - String name = rs.getString(1); - DBUser user = new DBUser(name); + final String name = rs.getString(1); + final StringProperties options = new StringProperties(rs); + + final DBUser user = new DBUser(name, options); listUser.put(name, user); } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "users") + ": " +e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "users") + ": " + e.getMessage()); + + } catch(Exception e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "users"); + throw new ExceptionDBGitRunTime(msg, e); } + return listUser; } @Override public Map getRoles() { - Map listRole = new HashMap(); - try { - String query = "SELECT R.GRANTEE, \n" + - "R.GRANTED_ROLE, R.ADMIN_OPTION, R.DEFAULT_ROLE FROM DBA_ROLE_PRIVS R \n" + - "WHERE R.GRANTEE = (SELECT USERNAME FROM DBA_USERS WHERE USERNAME = R.GRANTEE AND\n" + - "USERNAME != 'PUBLIC' AND USERNAME != 'SYSTEM'\n" + - "AND USERNAME != 'SYS' AND USERNAME != 'APPQOSSYS' AND USERNAME != 'OUTLN' \n" + - "AND USERNAME != 'DIP' AND USERNAME != 'DBSNMP' AND USERNAME != 'ORACLE_OCM')"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + final Map listRole = new HashMap(); + final String query = + "SELECT R.GRANTEE, \n" + + "R.GRANTED_ROLE, R.ADMIN_OPTION, R.DEFAULT_ROLE FROM DBA_ROLE_PRIVS R \n" + + "WHERE R.GRANTEE = (SELECT USERNAME FROM DBA_USERS WHERE USERNAME = R.GRANTEE AND\n" + + "USERNAME != 'PUBLIC' AND USERNAME != 'SYSTEM'\n" + + "AND USERNAME != 'SYS' AND USERNAME != 'APPQOSSYS' AND USERNAME != 'OUTLN' \n" + + "AND USERNAME != 'DIP' AND USERNAME != 'DBSNMP' AND USERNAME != 'ORACLE_OCM')"; + try ( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ) { + while(rs.next()){ - String name = rs.getString("GRANTED_ROLE"); - DBRole role = new DBRole(name); - rowToProperties(rs, role.getOptions()); + final String name = rs.getString("GRANTED_ROLE"); + final StringProperties options = new StringProperties(rs); + + final DBRole role = new DBRole(name, options); listRole.put(name, role); } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "roles") + ": " + e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "roles") + ": " + e.getMessage()); + + } catch(Exception e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "roles"); + throw new ExceptionDBGitRunTime(msg, e); } + return listRole; } @Override - public boolean userHasRightsToGetDdlOfOtherUsers() { - try { - String userName = getConnection().getSchema(); - - if (userName.equalsIgnoreCase("SYS")) - return true; - - PreparedStatement stmt = getConnection().prepareStatement - ("SELECT count(1) cnt FROM DBA_ROLE_PRIVS WHERE GRANTEE = ? and GRANTED_ROLE = 'SELECT_CATALOG_ROLE'"); - stmt.setString(1, userName); - ResultSet resultSet = stmt.executeQuery(); - resultSet.next(); - - if (resultSet.getInt(1) == 0) { - return false; - } else { - return true; - } - } catch (SQLException e) { - logger.error(e.getMessage()); - return false; - } + public Map getUDTs(String schema) { + return Collections.emptyMap(); } @Override - public IFactoryDBBackupAdapter getBackupAdapterFactory() { - return backupFactory; + public Map getDomains(String schema) { + return Collections.emptyMap(); } @Override - public DbType getDbType() { - return DbType.ORACLE; + public Map getEnums(String schema) { + return Collections.emptyMap(); } - + @Override - public String getDbVersion() { - try { - PreparedStatement stmt = getConnection().prepareStatement("SELECT version FROM V$INSTANCE"); - ResultSet resultSet = stmt.executeQuery(); - resultSet.next(); - - String result = resultSet.getString("version"); - resultSet.close(); - stmt.close(); - - return result; - } catch (SQLException e) { - return ""; - } + public DBUserDefinedType getUDT(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } @Override - public void createSchemaIfNeed(String schemaName) throws ExceptionDBGit { - try { - Statement st = connect.createStatement(); - ResultSet rs = st.executeQuery("select count(*) cnt from all_users where USERNAME = '" + schemaName.toUpperCase() + "'"); - rs.next(); - if (rs.getInt("cnt") == 0) { - StatementLogging stLog = new StatementLogging(connect, getStreamOutputSqlCommand(), isExecSql()); - stLog.execute("create USER \"" + schemaName.toUpperCase() + "\"\r\n" + - "IDENTIFIED BY \"" + schemaName.toUpperCase() + "\"\r\n" + - "DEFAULT TABLESPACE \"SYSTEM\"\r\n" + - "TEMPORARY TABLESPACE \"TEMP\"\r\n" + - "ACCOUNT UNLOCK"); - - stLog.execute("ALTER USER \"" + schemaName.toUpperCase() + "\" QUOTA UNLIMITED ON SYSTEM"); - stLog.close(); - } - - rs.close(); - st.close(); - } catch (SQLException e) { - throw new ExceptionDBGit(lang.getValue("errors", "adapter", "createSchema") + ": " + e.getLocalizedMessage()); - } - + public DBDomain getDomain(String schema, String name) { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } @Override - public boolean isReservedWord(String word) { - Set reservedWords = new HashSet<>(); + 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"); reservedWords.add("ALL"); @@ -1006,27 +1104,5 @@ public boolean isReservedWord(String word) { reservedWords.add("WHENEVER"); reservedWords.add("WHERE"); reservedWords.add("WITH"); - - return reservedWords.contains(word.toUpperCase()); - } - - @Override - public IFactoryDBConvertAdapter getConvertAdapterFactory() { - return convertFactory; - } - - - @Override - public void createRoleIfNeed(String roleName) throws ExceptionDBGit { - } - - @Override - public String getDefaultScheme() throws ExceptionDBGit { - try { - return getConnection().getSchema(); - } catch (SQLException e) { - throw new ExceptionDBGit(lang.getValue("errors", "adapter", "getSchema") + ": " + e.getLocalizedMessage()); - } - } } diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBBackupAdapterOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBBackupAdapterOracle.java index 9f60a8c..c896ff0 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBBackupAdapterOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBBackupAdapterOracle.java @@ -30,7 +30,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio String ddl = metaSql.getSqlObject().getSql(); String schema = metaSql.getSqlObject().getSchema(); - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); ddl = replaceNames(ddl, schema, objectName, stLog); @@ -54,7 +54,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio if (file.exists()) obj = metaSql.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else if (obj instanceof MetaTable) { MetaTable metaTable = (MetaTable) obj; metaTable.loadFromDB(); @@ -64,7 +64,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio if(!isExists(schema, objectName)) return obj; - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); if (isToSaveData()) { @@ -98,7 +98,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio if (file.exists()) obj = metaTable.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else if (obj instanceof MetaSequence) { MetaSequence metaSequence = (MetaSequence) obj; metaSequence.loadFromDB(); @@ -108,7 +108,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio String ddl = metaSequence.getSequence().getOptions().get("ddl").toString(); - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); ddl = replaceNames(ddl, schema, objectName, stLog); @@ -118,11 +118,10 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio if (file.exists()) obj = metaSequence.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "backup", "backupError").withParams(obj.getName()), e); } finally { stLog.close(); @@ -205,7 +204,7 @@ public boolean createSchema(StatementLogging stLog, String schema){ ResultSet rs = st.executeQuery("select count(*) cnt from all_users where USERNAME = '" + PREFIX + schema + "'"); rs.next(); if (rs.getInt("cnt") == 0) { - ConsoleWriter.detailsPrintLn(lang.getValue("general", "backup", "creatingSchema").withParams(PREFIX + schema)); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "creatingSchema").withParams(PREFIX + schema), messageLevel); stLog.execute("create USER \"" + PREFIX + schema + "\"\r\n" + "IDENTIFIED BY \"" + PREFIX + schema + "\"\r\n" + "DEFAULT TABLESPACE \"SYSTEM\"\r\n" + @@ -220,7 +219,7 @@ public boolean createSchema(StatementLogging stLog, String schema){ return true; } catch (SQLException e) { - ConsoleWriter.println(lang.getValue("errors", "backup", "cannotCreateSchema").withParams(e.getLocalizedMessage())); + ConsoleWriter.println(lang.getValue("errors", "backup", "cannotCreateSchema").withParams(e.getLocalizedMessage()), messageLevel); return false; } diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreFunctionOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreFunctionOracle.java index 24023e7..736d146 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreFunctionOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreFunctionOracle.java @@ -19,7 +19,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreFnc").withParams(obj.getName()), 1); try { if (obj instanceof MetaFunction) { MetaFunction restoreFunction = (MetaFunction)obj; @@ -44,14 +43,15 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "function", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestorePackageOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestorePackageOracle.java index 3a020f1..36c6b73 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestorePackageOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestorePackageOracle.java @@ -23,8 +23,7 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restorePkg").withParams(obj.getName()), 1); - try { + try { if (obj instanceof MetaPackage) { MetaPackage restorePackage = (MetaPackage) obj; Map pkgs = adapter.getPackages(restorePackage.getSqlObject().getSchema()); @@ -45,17 +44,18 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { executeSql(restorePackage.getSqlObject().getSql()); //TODO Восстановление привилегий } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "package", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreProcedureOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreProcedureOracle.java index 68562b7..16c04a0 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreProcedureOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreProcedureOracle.java @@ -20,8 +20,7 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restorePrc").withParams(obj.getName()), 1); - try { + try { if (obj instanceof MetaProcedure) { MetaProcedure restoreProcedure = (MetaProcedure)obj; Map prcds = adapter.getProcedures(restoreProcedure.getSqlObject().getSchema()); @@ -41,17 +40,18 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { st.execute(restoreProcedure.getSqlObject().getSql(), "/"); //TODO Восстановление привилегий } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "procedure", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreRoleOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreRoleOracle.java index 34d7b1d..4fbe8c9 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreRoleOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreRoleOracle.java @@ -19,7 +19,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreRole").withParams(obj.getName()), 1); try { if (obj instanceof MetaRole) { MetaRole restoreRole = (MetaRole)obj; @@ -60,15 +59,16 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } //TODO restore memberOfRole - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "role", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreSchemaOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreSchemaOracle.java index 124f148..ae867ba 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreSchemaOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreSchemaOracle.java @@ -18,7 +18,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreSchema").withParams(obj.getName()), 1); try { if (obj instanceof MetaSchema) { MetaSchema restoreSchema = (MetaSchema)obj; @@ -44,15 +43,16 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { setPassword(restoreSchema)); //TODO Восстановление привилегий } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "schema", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreSequenceOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreSequenceOracle.java index 44846c9..49f5b2b 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreSequenceOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreSequenceOracle.java @@ -19,7 +19,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreSeq").withParams(obj.getName()), 1); try { if (obj instanceof MetaSequence) { MetaSequence restoreSeq = (MetaSequence)obj; @@ -82,15 +81,16 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { st.execute(query); //TODO Восстановление привилегий } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "sequence", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTableDataOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTableDataOracle.java index 9736ced..0f0bc42 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTableDataOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTableDataOracle.java @@ -1,15 +1,9 @@ package ru.fusionsoft.dbgit.oracle; -import java.io.BufferedReader; -import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStreamReader; -import java.sql.Clob; import java.sql.Connection; import java.sql.ResultSet; -import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; @@ -17,7 +11,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.StringJoiner; import java.util.TreeMap; import java.util.stream.Collectors; @@ -29,10 +22,7 @@ import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.core.GitMetaDataManager; -import ru.fusionsoft.dbgit.core.SchemaSynonym; +import ru.fusionsoft.dbgit.core.*; import ru.fusionsoft.dbgit.data_table.BooleanData; import ru.fusionsoft.dbgit.data_table.DateData; import ru.fusionsoft.dbgit.data_table.ICellData; @@ -46,7 +36,6 @@ import ru.fusionsoft.dbgit.meta.IMetaObject; import ru.fusionsoft.dbgit.meta.MetaTable; import ru.fusionsoft.dbgit.meta.MetaTableData; -import ru.fusionsoft.dbgit.statement.PrepareStatementLogging; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; @@ -84,14 +73,14 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { if (getAdapter().getTable(schema, currentTableData.getTable().getName()) != null) { currentTableData.setDataTable(getAdapter().getTableData(schema, currentTableData.getTable().getName())); - ResultSet rs = currentTableData.getDataTable().getResultSet(); + ResultSet rs = currentTableData.getDataTable().resultSet(); TreeMapRowData mapRows = new TreeMapRowData(); MetaTable metaTable = new MetaTable(currentTableData.getTable()); metaTable.loadFromDB(currentTableData.getTable()); - ConsoleWriter.println("ids: " + metaTable.getIdColumns()); +// ConsoleWriter.println("ids: " + metaTable.getIdColumns()); if (rs != null) { while(rs.next()) { @@ -111,7 +100,10 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { return true; } else { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table data", obj.getType().getValue() + )); } } @@ -123,7 +115,6 @@ private void restoreTableDataOracle(MetaTableData restoreTableData, MetaTableDat try { String tblName = getPhisicalSchema(restoreTableData.getTable().getSchema()) + "." + restoreTableData.getTable().getName(); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "tableData").withParams(tblName) + "\n", 1); String insertQuery= ""; @@ -146,7 +137,7 @@ private void restoreTableDataOracle(MetaTableData restoreTableData, MetaTableDat } if(!diffTableData.entriesOnlyOnLeft().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "inserting"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "inserting"), messageLevel); for(RowData rowData:diffTableData.entriesOnlyOnLeft().values()) { ArrayList fieldsList = new ArrayList(rowData.getData().keySet()); @@ -166,26 +157,28 @@ private void restoreTableDataOracle(MetaTableData restoreTableData, MetaTableDat } } - ConsoleWriter.detailsPrintLn(insertQuery); + ConsoleWriter.detailsPrintln(insertQuery, messageLevel); if (needSeparator) st.execute(insertQuery, "/"); else st.execute(insertQuery); } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } if(!diffTableData.entriesOnlyOnRight().isEmpty()) { boolean isSuccessful = true; - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "deleting"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "deleting"), messageLevel); for(RowData rowData : diffTableData.entriesOnlyOnRight().values()) { Map primarykeys = getKeys(rowData); if (primarykeys.size() == 0) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.printlnRed(lang.getValue("errors", "restore", "pkNotFound").withParams(tblName)); +// ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); + ConsoleWriter.printlnRed(lang.getValue("errors", "restore", "pkNotFound") + .withParams(tblName), messageLevel + ); isSuccessful = false; break; } @@ -198,20 +191,20 @@ private void restoreTableDataOracle(MetaTableData restoreTableData, MetaTableDat st.execute(deleteQuery); } - if (isSuccessful) ConsoleWriter.detailsPrintlnGreen("OK"); + if (isSuccessful) ConsoleWriter.detailsPrintlnGreen(DBGitLang.getInstance().getValue("general", "meta", "ok"), messageLevel); } if(!diffTableData.entriesDiffering().isEmpty()) { boolean isSuccessful = true; - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "updating"), 2); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "updating"), messageLevel); for (ValueDifference diffRowData:diffTableData.entriesDiffering().values()) { if (!diffRowData.leftValue().getHashRow().equals(diffRowData.rightValue().getHashRow())) { Map primarykeys = getKeys(diffRowData.leftValue()); if (primarykeys.size() == 0) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.printlnRed(lang.getValue("general", "restore", "pkNotFound").withParams(tblName)); + ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail"), messageLevel); + ConsoleWriter.printlnRed(lang.getValue("general", "restore", "pkNotFound").withParams(tblName),messageLevel); isSuccessful = false; break; } @@ -248,12 +241,13 @@ private void restoreTableDataOracle(MetaTableData restoreTableData, MetaTableDat } } - if (isSuccessful) ConsoleWriter.detailsPrintlnGreen("OK"); + if (isSuccessful) ConsoleWriter.detailsPrintlnGreen(DBGitLang.getInstance().getValue("general", "meta", "ok"), messageLevel); } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(restoreTableData.getTable().getSchema() + "." + restoreTableData.getTable().getName()), e); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(restoreTableData.getTable().getSchema() + "." + restoreTableData.getTable().getName()) + , e + ); } finally { st.close(); } @@ -271,8 +265,8 @@ private Map getKeys(RowData rowData) { primarykeys.put(entry.getKey(), entry.getValue().convertToString()); } } catch (Exception e) { - ConsoleWriter.printlnRed(lang.getValue("general", "restore", "pkNotFound").withParams("")); - ConsoleWriter.printlnRed(e.getMessage()); + ConsoleWriter.printlnRed(lang.getValue("general", "restore", "pkNotFound").withParams(""),messageLevel); + ConsoleWriter.detailsPrintlnRed(e.getMessage(), messageLevel); } } }); @@ -282,7 +276,7 @@ private Map getKeys(RowData rowData) { private void restoreTableConstraintOracle(MetaTable table) throws Exception { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreConstr").withParams(table.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreConstr").withParams(table.getName()), messageLevel); IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); @@ -293,14 +287,12 @@ private void restoreTableConstraintOracle(MetaTable table) throws Exception { if(!constraint.getConstraintType().equalsIgnoreCase("p")) { String query = "alter table " + schema + "." + table.getTable().getName() + " add constraint "+ constraint.getName() + " " +constraint.getOptions().get("ddl").toString(); - ConsoleWriter.println(query); + ConsoleWriter.println(query, messageLevel); st.execute(query); } } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(table.getTable().getName()), e); } finally { st.close(); @@ -308,7 +300,7 @@ private void restoreTableConstraintOracle(MetaTable table) throws Exception { } private void removeTableConstraintsOracle(MetaTable table) throws Exception { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "delConstr").withParams(table.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "delConstr").withParams(table.getName()), messageLevel); IDBAdapter adapter = getAdapter(); StatementLogging st = new StatementLogging(adapter.getConnection(), adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); String schema = getPhisicalSchema(table.getTable().getSchema()); @@ -327,15 +319,15 @@ private void removeTableConstraintsOracle(MetaTable table) throws Exception { //String query = "if (OBJECT_ID(" + schema + "." + constraint.getName() + ")) then begin alter table " + schema + "." + table.getTable().getName() // + " drop constraint " + constraint.getName() + "; end"; - ConsoleWriter.println(dropQuery); + ConsoleWriter.println(dropQuery, messageLevel); st.execute(dropQuery, "/"); } } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "cannotRestore").withParams(schema + "." + table.getTable().getName()), e); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "cannotRestore").withParams(schema + "." + table.getTable().getName()) + , e + ); } finally { st.close(); } diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTableOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTableOracle.java index 0cecf82..d06d879 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTableOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTableOracle.java @@ -1,431 +1,427 @@ -package ru.fusionsoft.dbgit.oracle; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import com.google.common.collect.MapDifference; -import com.google.common.collect.Maps; -import com.google.common.collect.MapDifference.ValueDifference; - -import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.core.SchemaSynonym; -import ru.fusionsoft.dbgit.dbobjects.DBConstraint; -import ru.fusionsoft.dbgit.dbobjects.DBIndex; -import ru.fusionsoft.dbgit.dbobjects.DBTable; -import ru.fusionsoft.dbgit.dbobjects.DBTableField; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaTable; -import ru.fusionsoft.dbgit.statement.StatementLogging; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class DBRestoreTableOracle extends DBRestoreAdapter { - - @Override - public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { - if(Integer.valueOf(step).equals(0)) { - restoreTableOracle(obj); - return false; - } - /*if(Integer.valueOf(step).equals(1)) { - restoreTableFieldsOracle(obj); - return false; - }*/ - if(Integer.valueOf(step).equals(-21)) { - restoreTableIndexesOracle(obj); - return false; - } - if(Integer.valueOf(step).equals(-1)) { - restoreTableConstraintOracle(obj); - return false; - } - return true; - } - - public void restoreTableOracle(IMetaObject obj) throws Exception - { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - try { - if (obj instanceof MetaTable) { - - MetaTable restoreTable = (MetaTable)obj; - String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); - schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); - String tblName = schema+"."+restoreTable.getTable().getName(); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTable").withParams(tblName) + "\n", 1); - - Map tables = adapter.getTables(schema.toUpperCase()); - boolean exist = false; - if(!(tables.isEmpty() || tables == null)) { - for(DBTable table:tables.values()) { - if(restoreTable.getTable().getName().equalsIgnoreCase(table.getName())){ - exist = true; - - } - } - } - if(!exist){ - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "createTable"), 2); - String ddl = ""; - if (restoreTable.getTable().getOptions().get("ddl") != null) - ddl = restoreTable.getTable().getOptions().get("ddl").getData() - .replace("\"" + restoreTable.getTable().getSchema().toUpperCase() + "\"", "\"" + schema.toUpperCase() + "\""); - else { - DBTable table = restoreTable.getTable(); - - Comparator comparator = (o1, o2) -> o1.getOrder().compareTo(o2.getOrder()); - - ddl = "create table " + schema + "." + table.getName() + - " (" + restoreTable.getFields().values().stream() - .sorted(comparator) - .map(field -> "" + (adapter.isReservedWord(field.getName()) ? "\"" + field.getName() + "\" " : field.getName()) + " " + field.getTypeSQL()) - .collect(Collectors.joining(", ")) + ")"; - } - st.execute(ddl); - - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } else { - //restore tabl fields - Map currentFileds = adapter.getTableFields(schema, restoreTable.getTable().getName().toLowerCase()); - MapDifference diffTableFields = Maps.difference(restoreTable.getFields(),currentFileds); - - if(!diffTableFields.entriesOnlyOnLeft().isEmpty()){ - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "addColumns"), 2); - - Comparator comparator = (o1, o2) -> o1.getOrder().compareTo(o2.getOrder()); - - List values = diffTableFields.entriesOnlyOnLeft().values().stream().collect(Collectors.toList()); - values.sort(comparator); - - for(DBTableField tblField : values) { - st.execute("alter table "+ tblName +" add " + tblField.getName() + " " + tblField.getTypeSQL()); - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - - if(!diffTableFields.entriesOnlyOnRight().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "droppingColumns"), 2); - for(DBTableField tblField:diffTableFields.entriesOnlyOnRight().values()) { - st.execute("alter table "+ tblName +" drop column "+ tblField.getName()); - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - - if(!diffTableFields.entriesDiffering().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "modifyColumns"), 2); - - for(ValueDifference tblField:diffTableFields.entriesDiffering().values()) { - if(!tblField.leftValue().getName().equals(tblField.rightValue().getName())) { - st.execute("alter table "+ tblName +" rename column "+ tblField.rightValue().getName() +" to "+ tblField.leftValue().getName()); - } - - if(!tblField.leftValue().getTypeUniversal().equals(tblField.rightValue().getTypeUniversal())) { - st.execute("alter table "+ tblName +" modify "+ tblField.leftValue().getName() +" "+ tblField.leftValue().getTypeSQL()); - } - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - } - - ResultSet rs = st.executeQuery("SELECT COUNT(cons.constraint_name) constraintscount \n" + - "FROM all_constraints cons \n" + - "WHERE upper(owner) = upper('" + schema + "') and upper(table_name) = upper('" + restoreTable.getTable().getName()+ "') and constraint_name not like 'SYS%' and cons.constraint_type = 'P'"); - rs.next(); - Integer constraintsCount = Integer.valueOf(rs.getString("constraintscount")); - if(constraintsCount.intValue()>0) { - removeTableConstraintsOracle(obj); - } - // set primary key - boolean flagPkCreated = false; - for(DBConstraint tableconst: restoreTable.getConstraints().values()) { - if(tableconst.getConstraintType().equals("p")) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "addPk"), 2); - - if (tableconst.getOptions().get("ddl").toString().toLowerCase().startsWith("alter table")) - st.execute(tableconst.getOptions().get("ddl").toString().replace(" " +tableconst.getSchema() + ".", " " + schema + ".")); - else if (tableconst.getOptions().get("ddl").toString().toLowerCase().startsWith("primary key")) - st.execute("alter table "+ tblName +" add constraint PK_"+ tableconst.getName() + tableconst.getOptions().get("ddl").toString()); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - flagPkCreated = true; - break; - } - } - - if (!flagPkCreated) { - for(DBTableField field: restoreTable.getFields().values()) { - if (field.getIsPrimaryKey()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "addPk"), 2); - st.execute("alter table "+ tblName +" add constraint pk_" + restoreTable.getTable().getName() + "_" + field.getName() + " PRIMARY KEY (" + field.getName() + ")"); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - break; - } - } - } - - - } - else - { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (SQLException e1) { - ConsoleWriter.detailsPrintlnRed(lang.getValue(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage())); - //throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage()); - } catch (Exception e) { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - st.close(); - } - } - - public void restoreTableFieldsOracle(IMetaObject obj) throws Exception - { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - try { - if (obj instanceof MetaTable) { - MetaTable restoreTable = (MetaTable)obj; - String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); - schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); - String tblName = schema+"."+restoreTable.getTable().getName(); - Map tables = adapter.getTables(schema); - boolean exist = false; - if(!(tables.isEmpty() || tables == null)) { - for(DBTable table:tables.values()) { - if(restoreTable.getTable().getName().equals(table.getName())){ - exist = true; - } - } - } - if(!exist){ - st.execute(restoreTable.getTable().getOptions().get("ddl").getData()); - } - //restore tabl fields - Map currentFileds = adapter.getTableFields(schema, restoreTable.getTable().getName()); - MapDifference diffTableFields = Maps.difference(restoreTable.getFields(),currentFileds); - - if(!diffTableFields.entriesOnlyOnLeft().isEmpty()){ - for(DBTableField tblField:diffTableFields.entriesOnlyOnLeft().values()) { - st.execute("alter table "+ tblName +" add " + tblField.getName() + " " + tblField.getTypeSQL()); - } - } - - if(!diffTableFields.entriesOnlyOnRight().isEmpty()) { - for(DBTableField tblField:diffTableFields.entriesOnlyOnRight().values()) { - st.execute("alter table "+ tblName +" drop column "+ tblField.getName()); - } - } - - if(!diffTableFields.entriesDiffering().isEmpty()) { - for(ValueDifference tblField:diffTableFields.entriesDiffering().values()) { - if(!tblField.leftValue().getName().equals(tblField.rightValue().getName())) { - st.execute("alter table "+ tblName +" rename column "+ tblField.rightValue().getName() +" to "+ tblField.leftValue().getName()); - } - - if(!tblField.leftValue().getTypeSQL().equals(tblField.rightValue().getTypeSQL())) { - st.execute("alter table "+ tblName +" modify "+ tblField.leftValue().getName() +" "+ tblField.leftValue().getTypeSQL()); - } - } - } - - ResultSet rs = st.executeQuery("SELECT COUNT(cons.constraint_name)\n" + - "FROM all_constraints cons \n" + - "WHERE upper(owner) = upper('" + schema + "') and upper(table_name) = upper('" + tblName+ "') and constraint_name not like 'SYS%' and cons.constraint_type = 'P'"); - rs.next(); - Integer constraintsCount = Integer.valueOf(rs.getString("constraintscount")); - if(constraintsCount.intValue()>0) { - removeTableConstraintsOracle(obj); - } - // set primary key - for(DBConstraint tableconst: restoreTable.getConstraints().values()) { - if(tableconst.getConstraintType().equals("p")) { - st.execute(restoreTable.getConstraints().get("constraintDef").getOptions().get("ddl").toString()); - //st.execute("alter table "+ tblName +" add constraint PK_"+ tableconst.getName() + " primary key ("+tableconst.getName() + ")"); - break; - } - } - } - else - { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (SQLException e1) { - ConsoleWriter.detailsPrintlnRed(lang.getValue(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage())); - //throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage()); - } catch (Exception e) { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - st.close(); - } - } - - public void restoreTableIndexesOracle(IMetaObject obj) throws Exception - { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreIndex").withParams(obj.getName()), 1); - try { - if (obj instanceof MetaTable) { - MetaTable restoreTable = (MetaTable)obj; - String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); - schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); - Map tables = adapter.getTables(schema); - boolean exist = false; - if(!(tables.isEmpty() || tables == null)) { - for(DBTable table:tables.values()) { - if(restoreTable.getTable().getName().equals(table.getName())){ - exist = true; - Map currentIndexes = adapter.getIndexes(schema, table.getName()); - MapDifference diffInd = Maps.difference(restoreTable.getIndexes(), currentIndexes); - if(!diffInd.entriesOnlyOnLeft().isEmpty()) { - for(DBIndex ind:diffInd.entriesOnlyOnLeft().values()) { - ConsoleWriter.println(ind.getSql()); - if (ind.getSql().length() > 5 ) - st.execute(ind.getSql()); - } - } - if(!diffInd.entriesOnlyOnRight().isEmpty()) { - for(DBIndex ind:diffInd.entriesOnlyOnRight().values()) { - st.execute("drop index "+schema+"."+ind.getName()); - } - } - - //not fact, will check in future - } - } - } - if(!exist){ - for(DBIndex ind:restoreTable.getIndexes().values()) { - st.execute(ind.getSql()); - } - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - else - { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (SQLException e1) { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage()); - } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - st.close(); - } - } - - public void restoreTableConstraintOracle(IMetaObject obj) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreConstr").withParams(obj.getName()), 1); - try { - if (obj instanceof MetaTable) { - MetaTable restoreTable = (MetaTable)obj; - String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); - schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); - for(DBConstraint constrs :restoreTable.getConstraints().values()) { - if(!constrs.getConstraintType().equalsIgnoreCase("P")) { - //String tblName = schema+"."+restoreTable.getTable().getName(); - - st.execute(constrs.getOptions().get("ddl").toString().replace(" " + constrs.getSchema() + ".", " " + schema + ".")); - } - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - else - { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (SQLException e1) { - ConsoleWriter.detailsPrintlnRed(lang.getValue(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage())); - //throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage()); - } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - st.close(); - } - } - - public void removeTableConstraintsOracle(IMetaObject obj) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - try { - if (obj instanceof MetaTable) { - MetaTable table = (MetaTable)obj; - String schema = getPhisicalSchema(table.getTable().getSchema()); - schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); - Map constraints = table.getConstraints(); - for(DBConstraint constrs :constraints.values()) { - - String dropQuery = "declare cnt number;\r\n" + - "begin \r\n" + - "select count(*) into cnt from ALL_CONSTRAINTS where upper(CONSTRAINT_NAME) = upper('" + constrs.getName() + "') and upper(owner) = upper('" + schema + "');\r\n" + - " if (cnt > 0) \r\n" + - " then \r\n" + - " execute immediate('alter table " + schema + "." + table.getTable().getName() + " drop constraint " + constrs.getName() + "');\r\n" + - " end if;\r\n" + - "end;"; - - - st.execute(dropQuery, "/"); - } - //} - } - else - { - throw new ExceptionDBGitRestore("Error restore: Unable to remove TableConstraints."); - } - - } catch (SQLException e1) { - ConsoleWriter.detailsPrintlnRed(lang.getValue(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage())); - //throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage()); - } catch (Exception e) { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } - } - - /*public void removeIndexesOracle(IMetaObject obj) throws Exception { - - }*/ - - public void removeMetaObject(IMetaObject obj) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - - try { - - MetaTable tblMeta = (MetaTable)obj; - DBTable tbl = tblMeta.getTable(); - //String schema = getPhisicalSchema(tbl.getSchema()); - - st.execute("DROP TABLE " +tbl.getName()); - - // TODO Auto-generated method stub - } catch (SQLException e1) { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + "\n"+ e1.getLocalizedMessage()); - } catch (Exception e) { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); - } finally { - st.close(); - } - } - -} +package ru.fusionsoft.dbgit.oracle; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import com.google.common.collect.MapDifference; +import com.google.common.collect.Maps; +import com.google.common.collect.MapDifference.ValueDifference; + +import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; +import ru.fusionsoft.dbgit.core.SchemaSynonym; +import ru.fusionsoft.dbgit.dbobjects.DBConstraint; +import ru.fusionsoft.dbgit.dbobjects.DBIndex; +import ru.fusionsoft.dbgit.dbobjects.DBTable; +import ru.fusionsoft.dbgit.dbobjects.DBTableField; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaTable; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class DBRestoreTableOracle extends DBRestoreAdapter { + + @Override + public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + if(Integer.valueOf(step).equals(0)) { + restoreTableOracle(obj); + return false; + } + /*if(Integer.valueOf(step).equals(1)) { + restoreTableFieldsOracle(obj); + return false; + }*/ + if(Integer.valueOf(step).equals(-21)) { + restoreTableIndexesOracle(obj); + return false; + } + if(Integer.valueOf(step).equals(-1)) { + restoreTableConstraintOracle(obj); + return false; + } + return true; + } + + public void restoreTableOracle(IMetaObject obj) throws Exception + { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + try { + if (obj instanceof MetaTable) { + + MetaTable restoreTable = (MetaTable)obj; + String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); + schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); + String tblName = schema+"."+restoreTable.getTable().getName(); + + Map tables = adapter.getTables(schema.toUpperCase()); + boolean exist = false; + if(!(tables.isEmpty() || tables == null)) { + for(DBTable table:tables.values()) { + if(restoreTable.getTable().getName().equalsIgnoreCase(table.getName())){ + exist = true; + + } + } + } + if(!exist){ + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "createTable"), messageLevel); + String ddl = ""; + if (restoreTable.getTable().getOptions().get("ddl") != null) + ddl = restoreTable.getTable().getOptions().get("ddl").getData() + .replace("\"" + restoreTable.getTable().getSchema().toUpperCase() + "\"", "\"" + schema.toUpperCase() + "\""); + else { + DBTable table = restoreTable.getTable(); + + Comparator comparator = Comparator.comparing(DBTableField::getOrder); + + ddl = "create table " + schema + "." + table.getName() + + " (" + restoreTable.getFields().values().stream() + .sorted(comparator) + .map(field -> "" + (adapter.isReservedWord(field.getName()) ? "\"" + field.getName() + "\" " : field.getName()) + " " + field.getTypeSQL()) + .collect(Collectors.joining(", ")) + ")"; + } + st.execute(ddl); + + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } else { + //restore tabl fields + Map currentFileds = adapter.getTableFields(schema, restoreTable.getTable().getName().toLowerCase()); + MapDifference diffTableFields = Maps.difference(restoreTable.getFields(),currentFileds); + + if(!diffTableFields.entriesOnlyOnLeft().isEmpty()){ + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "addColumns"), messageLevel); + + Comparator comparator = Comparator.comparing(DBTableField::getOrder); + + List values = diffTableFields.entriesOnlyOnLeft().values().stream().collect(Collectors.toList()); + values.sort(comparator); + + for(DBTableField tblField : values) { + st.execute("alter table "+ tblName +" add " + tblField.getName() + " " + tblField.getTypeSQL()); + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + + if(!diffTableFields.entriesOnlyOnRight().isEmpty()) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "droppingColumns"), messageLevel); + for(DBTableField tblField:diffTableFields.entriesOnlyOnRight().values()) { + st.execute("alter table "+ tblName +" drop column "+ tblField.getName()); + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + + if(!diffTableFields.entriesDiffering().isEmpty()) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "modifyColumns"), messageLevel); + + for(ValueDifference tblField:diffTableFields.entriesDiffering().values()) { + if(!tblField.leftValue().getName().equals(tblField.rightValue().getName())) { + st.execute("alter table "+ tblName +" rename column "+ tblField.rightValue().getName() +" to "+ tblField.leftValue().getName()); + } + + if(!tblField.leftValue().getTypeUniversal().equals(tblField.rightValue().getTypeUniversal())) { + st.execute("alter table "+ tblName +" modify "+ tblField.leftValue().getName() +" "+ tblField.leftValue().getTypeSQL()); + } + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + } + + ResultSet rs = st.executeQuery("SELECT COUNT(cons.constraint_name) constraintscount \n" + + "FROM all_constraints cons \n" + + "WHERE upper(owner) = upper('" + schema + "') and upper(table_name) = upper('" + restoreTable.getTable().getName()+ "') and constraint_name not like 'SYS%' and cons.constraint_type = 'P'"); + rs.next(); + Integer constraintsCount = Integer.valueOf(rs.getString("constraintscount")); + if(constraintsCount.intValue()>0) { + removeTableConstraintsOracle(obj); + } + // set primary key + boolean flagPkCreated = false; + for(DBConstraint tableconst: restoreTable.getConstraints().values()) { + if(tableconst.getConstraintType().equals("p")) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "addPk"), messageLevel); + + if (tableconst.getOptions().get("ddl").toString().toLowerCase().startsWith("alter table")) + st.execute(tableconst.getOptions().get("ddl").toString().replace(" " +tableconst.getSchema() + ".", " " + schema + ".")); + else if (tableconst.getOptions().get("ddl").toString().toLowerCase().startsWith("primary key")) + st.execute("alter table "+ tblName +" add constraint PK_"+ tableconst.getName() + tableconst.getOptions().get("ddl").toString()); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + flagPkCreated = true; + break; + } + } + + if (!flagPkCreated) { + for(DBTableField field: restoreTable.getFields().values()) { + if (field.getIsPrimaryKey()) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "addPk"), messageLevel); + st.execute("alter table "+ tblName +" add constraint pk_" + restoreTable.getTable().getName() + "_" + field.getName() + " PRIMARY KEY (" + field.getName() + ")"); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + break; + } + } + } + + + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); + } + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } finally { + st.close(); + } + } + + public void restoreTableFieldsOracle(IMetaObject obj) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + try { + if (obj instanceof MetaTable) { + MetaTable restoreTable = (MetaTable)obj; + String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); + schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); + String tblName = schema+"."+restoreTable.getTable().getName(); + Map tables = adapter.getTables(schema); + boolean exist = false; + if(!(tables.isEmpty() || tables == null)) { + for(DBTable table:tables.values()) { + if(restoreTable.getTable().getName().equals(table.getName())){ + exist = true; + } + } + } + if(!exist){ + st.execute(restoreTable.getTable().getOptions().get("ddl").getData()); + } + //restore tabl fields + Map currentFileds = adapter.getTableFields(schema, restoreTable.getTable().getName()); + MapDifference diffTableFields = Maps.difference(restoreTable.getFields(),currentFileds); + + if(!diffTableFields.entriesOnlyOnLeft().isEmpty()){ + for(DBTableField tblField:diffTableFields.entriesOnlyOnLeft().values()) { + st.execute("alter table "+ tblName +" add " + tblField.getName() + " " + tblField.getTypeSQL()); + } + } + + if(!diffTableFields.entriesOnlyOnRight().isEmpty()) { + for(DBTableField tblField:diffTableFields.entriesOnlyOnRight().values()) { + st.execute("alter table "+ tblName +" drop column "+ tblField.getName()); + } + } + + if(!diffTableFields.entriesDiffering().isEmpty()) { + for(ValueDifference tblField:diffTableFields.entriesDiffering().values()) { + if(!tblField.leftValue().getName().equals(tblField.rightValue().getName())) { + st.execute("alter table "+ tblName +" rename column "+ tblField.rightValue().getName() +" to "+ tblField.leftValue().getName()); + } + + if(!tblField.leftValue().getTypeSQL().equals(tblField.rightValue().getTypeSQL())) { + st.execute("alter table "+ tblName +" modify "+ tblField.leftValue().getName() +" "+ tblField.leftValue().getTypeSQL()); + } + } + } + + ResultSet rs = st.executeQuery("SELECT COUNT(cons.constraint_name)\n" + + "FROM all_constraints cons \n" + + "WHERE upper(owner) = upper('" + schema + "') and upper(table_name) = upper('" + tblName+ "') and constraint_name not like 'SYS%' and cons.constraint_type = 'P'"); + rs.next(); + Integer constraintsCount = Integer.valueOf(rs.getString("constraintscount")); + if(constraintsCount.intValue()>0) { + removeTableConstraintsOracle(obj); + } + // set primary key + for(DBConstraint tableconst: restoreTable.getConstraints().values()) { + if(tableconst.getConstraintType().equals("p")) { + st.execute(restoreTable.getConstraints().get("constraintDef").getOptions().get("ddl").toString()); + //st.execute("alter table "+ tblName +" add constraint PK_"+ tableconst.getName() + " primary key ("+tableconst.getName() + ")"); + break; + } + } + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); + } + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } finally { + st.close(); + } + } + + public void restoreTableIndexesOracle(IMetaObject obj) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreIndex").withParams(obj.getName()), messageLevel); + try { + if (obj instanceof MetaTable) { + MetaTable restoreTable = (MetaTable)obj; + String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); + schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); + Map tables = adapter.getTables(schema); + boolean exist = false; + if(!(tables.isEmpty() || tables == null)) { + for(DBTable table:tables.values()) { + if(restoreTable.getTable().getName().equals(table.getName())){ + exist = true; + Map currentIndexes = adapter.getIndexes(schema, table.getName()); + MapDifference diffInd = Maps.difference(restoreTable.getIndexes(), currentIndexes); + if(!diffInd.entriesOnlyOnLeft().isEmpty()) { + for(DBIndex ind:diffInd.entriesOnlyOnLeft().values()) { +// ConsoleWriter.println(ind.getSql()); + if (ind.getSql().length() > 5 ) + st.execute(ind.getSql()); + } + } + if(!diffInd.entriesOnlyOnRight().isEmpty()) { + for(DBIndex ind:diffInd.entriesOnlyOnRight().values()) { + st.execute("drop index "+schema+"."+ind.getName()); + } + } + + //not fact, will check in future + } + } + } + if(!exist){ + for(DBIndex ind:restoreTable.getIndexes().values()) { + st.execute(ind.getSql()); + } + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); + } + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError") + .withParams(obj.getName()) + , e + ); + } finally { + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + st.close(); + } + } + + public void restoreTableConstraintOracle(IMetaObject obj) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreConstr") + .withParams(obj.getName()) + , messageLevel + ); + try { + if (obj instanceof MetaTable) { + MetaTable restoreTable = (MetaTable)obj; + String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); + schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); + for(DBConstraint constrs :restoreTable.getConstraints().values()) { + if(!constrs.getConstraintType().equalsIgnoreCase("P")) { + //String tblName = schema+"."+restoreTable.getTable().getName(); + + st.execute(constrs.getOptions().get("ddl").toString().replace(" " + constrs.getSchema() + ".", " " + schema + ".")); + } + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); + } + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } finally { + st.close(); + } + } + + public void removeTableConstraintsOracle(IMetaObject obj) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + try { + if (obj instanceof MetaTable) { + MetaTable table = (MetaTable)obj; + String schema = getPhisicalSchema(table.getTable().getSchema()); + schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); + Map constraints = table.getConstraints(); + for(DBConstraint constrs :constraints.values()) { + + String dropQuery = "declare cnt number;\r\n" + + "begin \r\n" + + "select count(*) into cnt from ALL_CONSTRAINTS where upper(CONSTRAINT_NAME) = upper('" + constrs.getName() + "') and upper(owner) = upper('" + schema + "');\r\n" + + " if (cnt > 0) \r\n" + + " then \r\n" + + " execute immediate('alter table " + schema + "." + table.getTable().getName() + " drop constraint " + constrs.getName() + "');\r\n" + + " end if;\r\n" + + "end;"; + + + st.execute(dropQuery, "/"); + } + //} + } + else + { + throw new ExceptionDBGitRestore("Error restore: Unable to remove TableConstraints."); + } + + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } + } + + /*public void removeIndexesOracle(IMetaObject obj) throws Exception { + + }*/ + + public void removeMetaObject(IMetaObject obj) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + + try { + + MetaTable tblMeta = (MetaTable)obj; + DBTable tbl = tblMeta.getTable(); + //String schema = getPhisicalSchema(tbl.getSchema()); + + st.execute("DROP TABLE " +tbl.getName()); + + // TODO Auto-generated method stub + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); + } finally { + st.close(); + } + } + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTriggerOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTriggerOracle.java index 3f9a13f..35aa832 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTriggerOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreTriggerOracle.java @@ -21,8 +21,7 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTrigger").withParams(obj.getName()), 1); - try { + try { if (obj instanceof MetaTrigger) { MetaTrigger restoreTrigger = (MetaTrigger)obj; Map trgs = adapter.getTriggers(restoreTrigger.getSqlObject().getSchema()); @@ -42,17 +41,18 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { executeSql(restoreTrigger.getSqlObject().getSql()); //TODO Восстановление привилегий } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "trigger", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreViewOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreViewOracle.java index 96de107..0df3c02 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreViewOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/DBRestoreViewOracle.java @@ -21,7 +21,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreView").withParams(obj.getName()), 1); try { if (obj instanceof MetaView) { MetaView restoreView = (MetaView)obj; @@ -44,15 +43,16 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { st.execute(restoreView.getSqlObject().getSql()); //TODO Восстановление привилегий } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "view", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/FactoryDBAdapterRestoreOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/FactoryDBAdapterRestoreOracle.java index a1808a8..23ed6b6 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/FactoryDBAdapterRestoreOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/FactoryDBAdapterRestoreOracle.java @@ -1,12 +1,9 @@ package ru.fusionsoft.dbgit.oracle; -import java.sql.Connection; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import ru.fusionsoft.dbgit.adapters.DBRestoreMetaNotSupport; -import ru.fusionsoft.dbgit.adapters.DBRestoreMetaSql; import ru.fusionsoft.dbgit.adapters.IDBAdapter; import ru.fusionsoft.dbgit.adapters.IDBAdapterRestoreMetaData; import ru.fusionsoft.dbgit.adapters.IFactoryDBAdapterRestoteMetaData; @@ -43,7 +40,10 @@ public IDBAdapterRestoreMetaData getAdapterRestore(IDBGitMetaType tp, IDBAdapter if (!restoreAdapters.containsKey(tp.getValue())) { //return new DBRestoreMetaNotSupport(); - ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "restore", "cannotRestore").withParams(tp.getValue())); + ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "restore", "cannotRestore") + .withParams(tp.getValue()) + , messageLevel + ); return null; } diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/FactoryDbConvertAdapterOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/FactoryDbConvertAdapterOracle.java index 2ff1b70..ce70254 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/FactoryDbConvertAdapterOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/FactoryDbConvertAdapterOracle.java @@ -6,6 +6,7 @@ import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.meta.DBGitMetaType; import ru.fusionsoft.dbgit.oracle.converters.TableConverterOracle; @@ -27,7 +28,11 @@ public class FactoryDbConvertAdapterOracle implements IFactoryDBConvertAdapter { @Override public IDBConvertAdapter getConvertAdapter(String objectType) throws Exception { if (!converters.containsKey(objectType)) { - ConsoleWriter.println("Cannot convert " + objectType + "!"); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("errors", "convert", "cannotConvert") + .withParams(objectType) + , 1 + ); return null; } else return converters.get(objectType); diff --git a/src/main/java/ru/fusionsoft/dbgit/oracle/converters/TableConverterOracle.java b/src/main/java/ru/fusionsoft/dbgit/oracle/converters/TableConverterOracle.java index f423a9b..b194886 100644 --- a/src/main/java/ru/fusionsoft/dbgit/oracle/converters/TableConverterOracle.java +++ b/src/main/java/ru/fusionsoft/dbgit/oracle/converters/TableConverterOracle.java @@ -5,6 +5,7 @@ import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.dbobjects.DBConstraint; @@ -25,9 +26,13 @@ public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) thr if (obj instanceof MetaTable) { MetaTable table = (MetaTable) obj; - - ConsoleWriter.println("Processing table " + table.getName()); - + + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingTable") + .withParams(table.getName()) + , messageLevel + ); + //types for (DBTableField field : table.getFields().values()) field.setTypeSQL(typeFromAnotherDB(objDbType, field)); @@ -54,14 +59,23 @@ public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) thr } private String indexFromPostgres(DBIndex index) { - ConsoleWriter.println("Converting table index " + index.getName() + " from postgresql to oracle..."); - + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingIndex") + .withParams(index.getName(), "postgresql", "oracle") + , messageLevel + ); + return ""; } private String constraintFromPostgres(MetaTable table, DBConstraint constraint) { - ConsoleWriter.println("Converting table constraint " + constraint.getName() + " from postgresql to oracle..."); - + + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingConstraint") + .withParams(constraint.getName(), "postgresql", "oracle") + , messageLevel + ); + String ddl = constraint.getOptions().get("ddl") .toString() .replace("ON UPDATE CASCADE", "") @@ -76,7 +90,13 @@ private String constraintFromPostgres(MetaTable table, DBConstraint constraint) } private String typeFromAnotherDB(DbType dbType, DBTableField field) { - ConsoleWriter.println("Converting table field " + field.getName() + " from " + dbType.toString().toLowerCase() + " to oracle..."); + + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingField") + .withParams(field.getName(), dbType.toString(), "oracle") + , messageLevel + ); + String result = ""; switch (field.getTypeUniversal()) { case STRING: diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBAdapterPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBAdapterPostgres.java index 0b6268f..14b7f95 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBAdapterPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBAdapterPostgres.java @@ -3,65 +3,43 @@ import java.sql.*; import java.text.MessageFormat; +import java.time.Period; import java.util.*; import java.util.concurrent.TimeUnit; -import ru.fusionsoft.dbgit.adapters.AdapterFactory; -import ru.fusionsoft.dbgit.adapters.DBAdapter; -import ru.fusionsoft.dbgit.adapters.IFactoryDBAdapterRestoteMetaData; -import ru.fusionsoft.dbgit.adapters.IFactoryDBBackupAdapter; -import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; -import ru.fusionsoft.dbgit.core.DBGitConfig; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitObjectNotFound; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; +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.*; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.core.db.FieldType; -import ru.fusionsoft.dbgit.data_table.MapFileData; -import ru.fusionsoft.dbgit.data_table.BooleanData; -import ru.fusionsoft.dbgit.data_table.DateData; -import ru.fusionsoft.dbgit.data_table.FactoryCellData; -import ru.fusionsoft.dbgit.data_table.LongData; -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.DBFunction; -import ru.fusionsoft.dbgit.dbobjects.DBIndex; -import ru.fusionsoft.dbgit.dbobjects.DBPackage; -import ru.fusionsoft.dbgit.dbobjects.DBProcedure; -import ru.fusionsoft.dbgit.dbobjects.DBRole; -import ru.fusionsoft.dbgit.dbobjects.DBSchema; -import ru.fusionsoft.dbgit.dbobjects.DBSequence; -import ru.fusionsoft.dbgit.dbobjects.DBTable; -import ru.fusionsoft.dbgit.dbobjects.DBTableData; -import ru.fusionsoft.dbgit.dbobjects.DBTableField; -import ru.fusionsoft.dbgit.dbobjects.DBTableRow; -import ru.fusionsoft.dbgit.dbobjects.DBTableSpace; -import ru.fusionsoft.dbgit.dbobjects.DBTrigger; -import ru.fusionsoft.dbgit.dbobjects.DBUser; -import ru.fusionsoft.dbgit.dbobjects.DBView; +import ru.fusionsoft.dbgit.dbobjects.*; import ru.fusionsoft.dbgit.meta.IMapMetaObject; import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.TreeMapMetaObject; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.LoggerUtil; import org.slf4j.Logger; import com.axiomalaska.jdbc.NamedParameterPreparedStatement; +import ru.fusionsoft.dbgit.utils.StringProperties; public class DBAdapterPostgres extends DBAdapter { - private Logger logger = LoggerUtil.getLogger(this.getClass()); - private FactoryDBAdapterRestorePostgres restoreFactory = new FactoryDBAdapterRestorePostgres(); - private FactoryDbConvertAdapterPostgres convertFactory = new FactoryDbConvertAdapterPostgres(); - private FactoryDBBackupAdapterPostgres backupFactory = new FactoryDBBackupAdapterPostgres(); - private static Set reservedWords = new HashSet<>(); + private final Logger logger = LoggerUtil.getLogger(this.getClass()); + private final FactoryDBAdapterRestorePostgres restoreFactory = new FactoryDBAdapterRestorePostgres(); + private final FactoryDbConvertAdapterPostgres convertFactory = new FactoryDbConvertAdapterPostgres(); + private final FactoryDBBackupAdapterPostgres backupFactory = new FactoryDBBackupAdapterPostgres(); + private final static Set reservedWords = new HashSet<>(); @Override public IFactoryDBAdapterRestoteMetaData getFactoryRestore() { return restoreFactory; } - + @Override public void startUpdateDB() { // TODO Auto-generated method stub @@ -73,833 +51,930 @@ public void endUpdateDB() { // TODO Auto-generated method stub } - + @Override public IMapMetaObject loadCustomMetaObjects() { - return null; + return new TreeMapMetaObject(Collections.emptyList()); } @Override public Map getSchemes() { - Map listScheme = new HashMap(); - try { - String query = "select nspname,usename,nspacl from pg_namespace,pg_user where nspname!='pg_toast' and nspname!='pg_temp_1'"+ - "and nspname!='pg_toast_temp_1' and nspname!='pg_catalog'"+ - "and nspname!='information_schema' and nspname!='pgagent'"+ - "and nspname!='pg_temp_3' and nspname!='pg_toast_temp_3'"+ - "and usesysid = nspowner"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listScheme = new HashMap(); + final String query = + "select nspname,usename,nspacl from pg_namespace,pg_user where nspname!='pg_toast' and nspname!='pg_temp_1'"+ + "and nspname!='pg_toast_temp_1' and nspname!='pg_catalog'"+ + "and nspname!='information_schema' and nspname!='pgagent'"+ + "and nspname!='pg_temp_3' and nspname!='pg_toast_temp_3'"+ + "and usesysid = nspowner"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ - String name = rs.getString("nspname"); - DBSchema scheme = new DBSchema(name); - rowToProperties(rs, scheme.getOptions()); - listScheme.put(name, scheme); - } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "schemes").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "schemes").toString(), e); - } + final String name = rs.getString("nspname"); + final DBSchema scheme = new DBSchema(name, new StringProperties(rs)); + listScheme.put(name, scheme); + } + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "schemes").toString(); + throw new ExceptionDBGitRunTime(msg, e); + } return listScheme; + } - + @Override public Map getTableSpaces() { - Map listTableSpace = new HashMap(); - try { - String query = "SELECT tblspaces.spcname,tblspaces.spcacl,tblspaces.spcoptions,users.usename,pg_tablespace_location(tblspacesoid.oid) " + - "FROM pg_tablespace as tblspaces,pg_user as users,(Select oid FROM pg_tablespace where spcname!='pg_default' and spcname!='pg_global') as tblspacesoid " + - "WHERE users.usesysid=tblspaces.spcowner and spcname!='pg_default' and spcname!='pg_global' and tblspacesoid.oid=tblspaces.oid"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listTableSpace = new HashMap(); + final String query = + "SELECT tblspaces.spcname,tblspaces.spcacl,tblspaces.spcoptions,users.usename,pg_tablespace_location(tblspacesoid.oid) " + + "FROM pg_tablespace as tblspaces,pg_user as users,(Select oid FROM pg_tablespace where spcname!='pg_default' and spcname!='pg_global') as tblspacesoid " + + "WHERE users.usesysid=tblspaces.spcowner and spcname!='pg_default' and spcname!='pg_global' and tblspacesoid.oid=tblspaces.oid"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ - String name = rs.getString("spcname"); - DBTableSpace dbTableSpace = new DBTableSpace(name); - rowToProperties(rs, dbTableSpace.getOptions()); + final String name = rs.getString("spcname"); + final DBTableSpace dbTableSpace = new DBTableSpace(name, new StringProperties(rs)); listTableSpace.put(name, dbTableSpace); - } - stmt.close(); - }catch(Exception e) { - logger.error(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); + } + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tablespace").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listTableSpace; } @Override public Map getSequences(String schema) { - Map listSequence = new HashMap(); - try { - Connection connect = getConnection(); - String query = - "select s.sequence_name, rol.rolname as owner, s.start_value, s.minimum_value, s.maximum_value, s.increment, s.cycle_option " + - "from pg_class cls " + - " join pg_roles rol on rol.oid = cls.relowner " + - " join pg_namespace nsp on nsp.oid = cls.relnamespace " + - " join information_schema.sequences s on cls.relname = s.sequence_name " + - "where nsp.nspname not in ('information_schema', 'pg_catalog') " + - " and nsp.nspname not like 'pg_toast%' " + - " and cls.relkind = 'S' and s.sequence_schema = :schema "; - - NamedParameterPreparedStatement stmt = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(connect, query); - stmt.setString("schema", schema); - - ResultSet rs = stmt.executeQuery(); + final Map listSequence = new HashMap<>(); + final String query = MessageFormat.format( + "select s.sequence_name, rol.rolname as owner, s.start_value, s.minimum_value, s.maximum_value, s.increment, s.cycle_option, cl.relname as blocking_table \n" + + "from pg_class cls \n" + + " join pg_roles rol on rol.oid = cls.relowner \n" + + " join pg_namespace nsp on nsp.oid = cls.relnamespace \n" + + " join information_schema.sequences s on cls.relname = s.sequence_name \n" + + " left join pg_depend d on d.objid=cls.oid and d.classid=''pg_class''::regclass and d.refclassid=''pg_class''::regclass\n" + + " left join pg_class cl on cl.oid = d.refobjid and d.deptype=''a'' \n" + + "where nsp.nspname not in (''information_schema'', ''pg_catalog'')\n" + + " and nsp.nspname not like ''pg_toast%'' \n" + + " and cls.relkind = ''S'' and s.sequence_schema = ''{0}''", + schema + ); + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + while(rs.next()){ - String nameSeq = rs.getString("sequence_name"); - DBSequence sequence = new DBSequence(); - sequence.setName(nameSeq); - sequence.setSchema(schema); - sequence.setValue(0L); - rowToProperties(rs, sequence.getOptions()); + final String nameSeq = rs.getString("sequence_name"); + final String ownerSeq = rs.getString("blocking_table"); + final Long valueSeq = 0L; + //TODO find actual value + + final DBSequence sequence = new DBSequence(nameSeq, new StringProperties(rs), schema, ownerSeq, Collections.emptySet(), valueSeq); listSequence.put(nameSeq, sequence); } - stmt.close(); - }catch(Exception e) { - logger.error(e.getMessage(), e); - throw new ExceptionDBGitRunTime(e.getMessage(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "sequence").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return listSequence; } @Override public DBSequence getSequence(String schema, String name) { - try { - Connection connect = getConnection(); - String query = - "select s.sequence_name, rol.rolname as owner, s.start_value, s.minimum_value, s.maximum_value, s.increment, s.cycle_option " + - "from pg_class cls " + - " join pg_roles rol on rol.oid = cls.relowner " + - " join pg_namespace nsp on nsp.oid = cls.relnamespace " + - " join information_schema.sequences s on cls.relname = s.sequence_name " + - "where nsp.nspname not in ('information_schema', 'pg_catalog') " + - " and nsp.nspname not like 'pg_toast%' " + - " and cls.relkind = 'S' and s.sequence_schema = :schema and s.sequence_name = :name "; - - NamedParameterPreparedStatement stmt = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(connect, query); - stmt.setString("schema", schema); - stmt.setString("name", name); - + + final String query = + "select s.sequence_name, rol.rolname as owner, s.start_value, s.minimum_value, s.maximum_value, s.increment, s.cycle_option, cl.relname as blocking_table \n" + + "from pg_class cls \n" + + " join pg_roles rol on rol.oid = cls.relowner \n" + + " join pg_namespace nsp on nsp.oid = cls.relnamespace \n" + + " join information_schema.sequences s on cls.relname = s.sequence_name \n" + + " left join pg_depend d on d.objid=cls.oid and d.classid='pg_class'::regclass and d.refclassid='pg_class'::regclass\n" + + " left join pg_class cl on cl.oid = d.refobjid and d.deptype='a' \n" + + "where nsp.nspname not in ('information_schema', 'pg_catalog') \n" + + " and nsp.nspname not like 'pg_toast%' \n" + + " and cls.relkind = 'S' and s.sequence_schema = :schema and s.sequence_name = :name "; + + try ( + PreparedStatement stmt = preparedStatement(getConnection(), query, ImmutableMap.of("schema", schema, "name", name)); ResultSet rs = stmt.executeQuery(); - DBSequence sequence = null; - while (rs.next()) { - String nameSeq = rs.getString("sequence_name"); - sequence = new DBSequence(); - sequence.setName(nameSeq); - sequence.setSchema(schema); - sequence.setValue(0L); - rowToProperties(rs, sequence.getOptions()); + ) { + if (rs.next()) { + //TODO find actual value + final Long valueSeq = 0L; + final String nameSeq = rs.getString("sequence_name"); + final String ownerSeq = rs.getString("blocking_table"); + return new DBSequence(nameSeq, new StringProperties(rs), schema, ownerSeq, Collections.emptySet(), valueSeq); + + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - stmt.close(); - return sequence; - }catch(Exception e) { - logger.error(e.getMessage(), e); - throw new ExceptionDBGitRunTime(e.getMessage(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "sequence").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public Map getTables(String schema) { - Map listTable = new HashMap(); - try { - String query = - "select \n" + - " tablename as table_name,\n" + - " tableowner as owner,\n" + - " tablespace,hasindexes,hasrules,hastriggers, \n" + - " obj_description(to_regclass('\"' || schemaname || '\".\"' || tablename || '\"')::oid) table_comment, ( \n" + - " select array_agg(distinct n2.nspname || '/' || c2.relname || '.tbl') as dependencies\n" + - " FROM pg_catalog.pg_constraint c \n" + - " JOIN ONLY pg_catalog.pg_class c1 ON c1.oid = c.conrelid\n" + - " JOIN ONLY pg_catalog.pg_class c2 ON c2.oid = c.confrelid\n" + - " JOIN ONLY pg_catalog.pg_namespace n2 ON n2.oid = c2.relnamespace\n" + - " WHERE c.conrelid = to_regclass('\"' || schemaname || '\".\"' || tablename || '\"')::oid\n" + - " and c1.relkind = 'r' AND c.contype = 'f'\n" + - " )\n" + - "from pg_tables \n" + - "where upper(schemaname) = upper(:schema)"; - Connection connect = getConnection(); - - NamedParameterPreparedStatement stmt = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(connect, query); - stmt.setString("schema", schema); - + final Map listTable = new HashMap(); + final String query = + "SELECT \n" + + " tablename AS table_name,\n" + + " tableowner AS owner,\n" + + " tablespace, hasindexes, hasrules, hastriggers, \n" + + " obj_description( " + + " (('\"' || schemaname || '\".\"' || tablename || '\"')::regclass)::oid" + + " ) AS table_comment,\n" + + " (\n" + + " SELECT array_agg( distinct n2.nspname || '/' || c2.relname || '.tbl' ) AS dependencies\n" + + " FROM pg_catalog.pg_constraint c \n" + + " JOIN ONLY pg_catalog.pg_class c1 ON c1.oid = c.conrelid\n" + + " JOIN ONLY pg_catalog.pg_class c2 ON c2.oid = c.confrelid\n" + + " JOIN ONLY pg_catalog.pg_namespace n2 ON n2.oid = c2.relnamespace\n" + + " WHERE c.conrelid = (('\"' || schemaname || '\".\"' || tablename || '\"')::regclass)::oid\n" + + " and c1.relkind = 'r' AND c.contype = 'f'\n" + + " ) " + + " AS dependencies, \n" + + ( (getDbVersionNumber() >= 10) + ? " pg_get_partkeydef((\n" + + " SELECT oid \n" + + " FROM pg_class \n" + + " WHERE relname = tablename \n" + + " AND relnamespace = (select oid from pg_namespace where nspname = :schema )\n" + + " )) \n" + + " AS partkeydef, \n" + + " pg_get_expr(child.relpartbound, child.oid) " + + " AS pg_get_expr, \n" + : " " + ) + + " parent.relname AS parent \n" + + "FROM pg_tables \n" + + "LEFT OUTER JOIN pg_inherits on (SELECT oid FROM pg_class WHERE relname = tablename and relnamespace = (select oid from pg_namespace where nspname = :schema)) = pg_inherits.inhrelid \n" + + "LEFT OUTER JOIN pg_class parent ON pg_inherits.inhparent = parent.oid \n" + + "LEFT OUTER JOIN pg_class child ON pg_inherits.inhrelid = child.oid \n" + + "WHERE upper(schemaname) = upper(:schema)"; + + try ( + PreparedStatement stmt = preparedStatement(getConnection(), query, ImmutableMap.of("schema", schema)); ResultSet rs = stmt.executeQuery(); + ) { + + while(rs.next()){ - String nameTable = rs.getString("table_name"); - DBTable table = new DBTable(nameTable); - table.setSchema(schema); - table.setComment(rs.getString("table_comment")); - if(rs.getArray("dependencies") != null){ - table.setDependencies(new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray()))); - } else table.setDependencies(new HashSet<>()); - rowToProperties(rs, table.getOptions()); + final String nameTable = rs.getString("table_name"); + final String ownerTable = rs.getString("owner"); + final String commentTable = rs.getString("table_comment"); + final Set dependencies = rs.getArray("dependencies") != null + ? new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())) + : Collections.emptySet(); + + if (rs.getString("parent") != null) { + dependencies.add(schema + "/" + rs.getString("parent") + ".tbl"); + } + + final DBTable table = new DBTable(nameTable, new StringProperties(rs), schema, ownerTable, dependencies, commentTable); listTable.put(nameTable, table); } - stmt.close(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + } catch (Exception e) { + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listTable; } @Override public DBTable getTable(String schema, String name) { - String query = - "select \n" + - " tablename as table_name,\n" + - " tableowner as owner,\n" + - " tablespace,hasindexes,hasrules,hastriggers, \n" + - " obj_description(to_regclass('\"' || schemaname || '\".\"' || tablename || '\"')::oid) table_comment, ( \n" + - " select array_agg(distinct n2.nspname || '/' || c2.relname || '.tbl') as dependencies\n" + - " FROM pg_catalog.pg_constraint c \n" + - " JOIN ONLY pg_catalog.pg_class c1 ON c1.oid = c.conrelid\n" + - " JOIN ONLY pg_catalog.pg_class c2 ON c2.oid = c.confrelid\n" + - " JOIN ONLY pg_catalog.pg_namespace n2 ON n2.oid = c2.relnamespace\n" + - " WHERE c.conrelid = to_regclass('\"' || schemaname || '\".\"' || tablename || '\"')::oid\n" + - " and c1.relkind = 'r' AND c.contype = 'f'\n" + - " )" + - "from pg_tables \n" + - "where upper(schemaname) = upper('"+schema+"') \n" + - "and tablename = '"+name+"'\n"; - try { + final String query = + "SELECT \n" + + " tablename AS table_name,\n" + + " tableowner AS owner,\n" + + " tablespace, hasindexes, hasrules, hastriggers, \n" + + " obj_description((('\"' || schemaname || '\".\"' || tablename || '\"')::regclass)::oid) AS table_comment,\n" + + " (\n" + + " SELECT array_agg( distinct n2.nspname || '/' || c2.relname || '.tbl' ) AS dependencies\n" + + " FROM pg_catalog.pg_constraint c \n" + + " JOIN ONLY pg_catalog.pg_class c1 ON c1.oid = c.conrelid\n" + + " JOIN ONLY pg_catalog.pg_class c2 ON c2.oid = c.confrelid\n" + + " JOIN ONLY pg_catalog.pg_namespace n2 ON n2.oid = c2.relnamespace\n" + + " WHERE c.conrelid = (('\"' || schemaname || '\".\"' || tablename || '\"')::regclass)::oid\n" + + " and c1.relkind = 'r' AND c.contype = 'f'\n" + + " ) " + + " AS dependencies, \n" + + ( (getDbVersionNumber() >= 10) + ? " pg_get_partkeydef((\n" + + " SELECT oid \n" + + " FROM pg_class \n" + + " WHERE relname = tablename \n" + + " AND relnamespace = (select oid from pg_namespace where nspname = :schema )\n" + + " )) \n" + + " AS partkeydef, \n" + + " pg_get_expr(child.relpartbound, child.oid) " + + " AS pg_get_expr, \n" + : " " + ) + + " parent.relname AS parent \n" + + "FROM pg_tables \n" + + "LEFT OUTER JOIN pg_inherits on (SELECT oid FROM pg_class WHERE relname = tablename and relnamespace = (select oid from pg_namespace where nspname = :schema)) = pg_inherits.inhrelid \n" + + "LEFT OUTER JOIN pg_class parent ON pg_inherits.inhparent = parent.oid \n" + + "LEFT OUTER JOIN pg_class child ON pg_inherits.inhrelid = child.oid \n" + + "WHERE upper(schemaname) = upper(:schema)" + + "AND tablename = :name"; + try ( + PreparedStatement stmt = preparedStatement(getConnection(), query, ImmutableMap.of("schema", schema, "name", name)); + ResultSet rs = stmt.executeQuery(); + ) { - Connection connect = getConnection(); - - Statement stmt = connect.createStatement(); - - ResultSet rs = stmt.executeQuery(query); + if (rs.next()) { + final String nameTable = rs.getString("table_name"); + final String ownerTable = rs.getString("owner"); + final String commentTable = rs.getString("table_comment"); + final Set dependencies = rs.getArray("dependencies") != null + ? new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())) + : Collections.emptySet(); - DBTable table = null; - - while (rs.next()) { - String nameTable = rs.getString("table_name"); - table = new DBTable(nameTable); - table.setSchema(schema); - table.setComment(rs.getString("table_comment")); - if(rs.getArray("dependencies") != null){ - table.setDependencies(new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray()))); - } else table.setDependencies(new HashSet<>()); - rowToProperties(rs, table.getOptions()); + if (rs.getString("parent") != null) { + dependencies.add(schema + "/" + rs.getString("parent") + ".tbl"); + } + + return new DBTable(nameTable, new StringProperties(rs), schema, ownerTable, dependencies, commentTable); + + } else { + final String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - stmt.close(); - return table; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public Map getTableFields(String schema, String nameTable) { - - try { - Map listField = new HashMap(); - - String query = - "SELECT distinct col.column_name,col.is_nullable,col.data_type, col.udt_name::regtype dtype,col.character_maximum_length, col.column_default, tc.constraint_name, " + - "case\r\n" + - " when lower(data_type) in ('integer', 'numeric', 'smallint', 'double precision', 'bigint') then 'number' \r\n" + - " when lower(data_type) in ('character varying', 'char', 'character', 'varchar') then 'string'\r\n" + - " when lower(data_type) in ('timestamp without time zone', 'timestamp with time zone', 'date') then 'date'\r\n" + - " when lower(data_type) in ('boolean') then 'boolean'\r\n" + - " when lower(data_type) in ('text') then 'text'\r\n" + - " when lower(data_type) in ('bytea') then 'binary'" + - " else 'native'\r\n" + - " end tp, " + - " case when lower(data_type) in ('char', 'character') then true else false end fixed, " + - " pgd.description," + - "col.* FROM " + - "information_schema.columns col " + - "left join information_schema.key_column_usage kc on col.table_schema = kc.table_schema and col.table_name = kc.table_name and col.column_name=kc.column_name " + - "left join information_schema.table_constraints tc on col.table_schema = kc.table_schema and col.table_name = kc.table_name and kc.constraint_name = tc.constraint_name and tc.constraint_type = 'PRIMARY KEY' " + - "left join pg_catalog.pg_statio_all_tables st on st.schemaname = col.table_schema and st.relname = col.table_name " + - "left join pg_catalog.pg_description pgd on (pgd.objoid=st.relid and pgd.objsubid=col.ordinal_position) " + - "where upper(col.table_schema) = upper(:schema) and col.table_name = :table " + - "order by col.column_name "; - Connection connect = getConnection(); - - NamedParameterPreparedStatement stmt = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(connect, query); - stmt.setString("schema", schema); - stmt.setString("table", nameTable); + Map listField = new HashMap(); + String query = + "SELECT distinct col.column_name,col.is_nullable,col.data_type, col.udt_name::regtype dtype,col.character_maximum_length, col.column_default, tc.constraint_name, " + + "case\r\n" + + " when lower(data_type) in ('integer', 'numeric', 'smallint', 'double precision', 'bigint') then 'number' \r\n" + + " when lower(data_type) in ('character varying', 'char', 'character', 'varchar') then 'string'\r\n" + + " when lower(data_type) in ('timestamp without time zone', 'timestamp with time zone', 'date') then 'date'\r\n" + + " when lower(data_type) in ('boolean') then 'boolean'\r\n" + + " when lower(data_type) in ('text') then 'text'\r\n" + + " when lower(data_type) in ('bytea') then 'binary'" + + " else 'native'\r\n" + + " end tp, " + + " case when lower(data_type) in ('char', 'character') then true else false end fixed, " + + " pgd.description," + + "col.* FROM " + + "information_schema.columns col " + + "left join information_schema.key_column_usage kc on col.table_schema = kc.table_schema and col.table_name = kc.table_name and col.column_name=kc.column_name " + + "left join information_schema.table_constraints tc on col.table_schema = kc.table_schema and col.table_name = kc.table_name and kc.constraint_name = tc.constraint_name and tc.constraint_type = 'PRIMARY KEY' " + + "left join pg_catalog.pg_statio_all_tables st on st.schemaname = col.table_schema and st.relname = col.table_name " + + "left join pg_catalog.pg_description pgd on (pgd.objoid=st.relid and pgd.objsubid=col.ordinal_position) " + + "where upper(col.table_schema) = upper(:schema) and col.table_name = :table " + + "order by col.column_name "; + try ( + PreparedStatement stmt = preparedStatement(getConnection(), query, ImmutableMap.of("schema", schema, "table", nameTable)); ResultSet rs = stmt.executeQuery(); - while(rs.next()){ - DBTableField field = new DBTableField(); - - field.setName(rs.getString("column_name")); - field.setDescription(rs.getString("description")); - field.setNameExactly(!rs.getString("column_name").equals(rs.getString("column_name").toLowerCase())); - if (rs.getString("constraint_name") != null) { - field.setIsPrimaryKey(true); - } - String typeSQL = getFieldType(rs); - field.setTypeSQL(typeSQL); - field.setIsNullable( !typeSQL.toLowerCase().contains("not null")); - field.setTypeUniversal(FieldType.fromString(rs.getString("tp"))); - field.setFixed(false); - field.setLength(rs.getInt("character_maximum_length")); - field.setPrecision(rs.getInt("numeric_precision")); - field.setScale(rs.getInt("numeric_scale")); - field.setFixed(rs.getBoolean("fixed")); - field.setOrder(rs.getInt("ordinal_position")); - field.setDefaultValue(rs.getString("column_default")); - listField.put(field.getName(), field); + ) { + + + while(rs.next()){ + final String typeSQL = getFieldType(rs); + final String nameField = rs.getString("column_name"); + final String descField = rs.getString("description"); + final String columnDefault = rs.getString("column_default"); + final boolean isFixed = rs.getBoolean("fixed"); + final boolean isPrimaryKey = rs.getString("constraint_name") != null; + final boolean isNullable = !typeSQL.toLowerCase().contains("not null"); + final FieldType typeUniversal = FieldType.fromString(rs.getString("tp")); +// System.out.println(( +// nameField +// + " > " +// + typeSQL +// + " (" +// + typeUniversal.toString() +// + ")" +// )); + final FieldType actualTypeUniversal = typeUniversal.equals(FieldType.TEXT) ? FieldType.STRING_NATIVE : typeUniversal; + final int length = rs.getInt("character_maximum_length"); + final int precision = rs.getInt("numeric_precision"); + final int scale = rs.getInt("numeric_scale"); + final int ordinalPosition = rs.getInt("ordinal_position"); + + + final DBTableField field = new DBTableField( + nameField, descField, isPrimaryKey, isNullable, + typeSQL, actualTypeUniversal, ordinalPosition, columnDefault, + length, scale, precision, isFixed + ); + + listField.put(nameField, field); } - stmt.close(); - - return listField; - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); - } + + + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); + } + + return listField; } - protected String getFieldType(ResultSet rs) { + private String getFieldType(ResultSet rs) { try { - StringBuilder type = new StringBuilder(); + final StringBuilder type = new StringBuilder(); type.append(rs.getString("dtype")); - + Integer max_length = rs.getInt("character_maximum_length"); if (!rs.wasNull()) { type.append("("+max_length.toString()+")"); } if (rs.getString("is_nullable").equals("NO")){ type.append(" NOT NULL"); - } - + } + return type.toString(); - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tables").toString(), e); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "tables").toString(), e); - } + } catch(Exception e) { + final String msg = lang.getValue("errors", "adapter", "tables").toString(); + throw new ExceptionDBGitRunTime(msg, e); + } } @Override public Map getIndexes(String schema, String nameTable) { - Map indexes = new HashMap<>(); - try { - String query = "select i.schemaname,\r\n" + - "i.tablename, \r\n" + - "i.indexname, \r\n" + - "i.tablespace, \r\n" + - "i.indexdef as ddl \r\n" + - "from \r\n" + - "pg_indexes as i JOIN pg_class as cl \r\n" + - " on i.indexname = cl.relname\r\n" + - "JOIN pg_index AS idx \r\n" + - " ON cl.oid = idx.indexrelid\r\n" + - "where i.tablename not like 'pg%' and i.schemaname = :schema and i.tablename = :table and idx.indisprimary = false -- and idx.indisunique=false "; - - Connection connect = getConnection(); - NamedParameterPreparedStatement stmt = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(connect, query); - stmt.setString("schema", schema); - stmt.setString("table", nameTable); + final Map indexes = new HashMap<>(); + final String query = + "SELECT " + + " i.schemaname,\r\n" + + " i.tablename, \r\n" + + " i.indexname, \r\n" + + " i.tablespace, \r\n" + + " i.indexdef AS ddl, \r\n" + + " t.tableowner AS owner \r\n" + + "FROM pg_indexes AS i " + + "JOIN pg_class AS cl ON i.indexname = cl.relname\r\n" + + "JOIN pg_index AS idx ON cl.oid = idx.indexrelid\r\n" + + "JOIN pg_tables AS t ON i.schemaname = t.schemaname AND i.tablename = t.tablename\r\n" + + "WHERE i.tablename not like 'pg%' " + + "AND i.schemaname = :schema " + + "AND i.tablename = :table and idx.indisprimary = false " + + "-- AND idx.indisunique=false "; + try ( + PreparedStatement stmt = preparedStatement(getConnection(), query, ImmutableMap.of("schema", schema, "table", nameTable)); ResultSet rs = stmt.executeQuery(); + ){ + while(rs.next()){ - DBIndex index = new DBIndex(); - index.setName(rs.getString("indexname")); - index.setSchema(schema); - rowToProperties(rs, index.getOptions()); - indexes.put(index.getName(), index); + final String name = rs.getString("indexname"); + final String owner = rs.getString("owner"); + final String ddl = rs.getString("ddl"); + + final DBIndex index = new DBIndex(name, new StringProperties(rs), schema, owner, Collections.emptySet(), ddl); + indexes.put(name, index); } - stmt.close(); - + return indexes; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "indexes").toString()); - throw new ExceptionDBGitRunTime(e.getMessage()); + + } catch(Exception e) { + String msg = lang.getValue("errors", "adapter", "indexes").toString(); + throw new ExceptionDBGitRunTime(msg, e); } - + } @Override public Map getConstraints(String schema, String nameTable) { - Map constraints = new HashMap<>(); - try { - /* - String query = "select conname as constraint_name,contype as constraint_type, " + - " pg_catalog.pg_get_constraintdef(r.oid, true) as ddl " + - "from " + - " pg_class c " + - " join pg_namespace n on n.oid = c.relnamespace " + - " join pg_catalog.pg_constraint r on r.conrelid = c.relfilenode " + - "WHERE " + - " relname = :table and nspname = :schema and c.relkind = 'r'"; - */ - - - String query = "SELECT conname as constraint_name,contype as constraint_type, \r\n" + - " pg_catalog.pg_get_constraintdef(con.oid, true) as ddl\r\n" + - " FROM pg_catalog.pg_constraint con\r\n" + - " INNER JOIN pg_catalog.pg_class rel\r\n" + - " ON rel.oid = con.conrelid\r\n" + - " INNER JOIN pg_catalog.pg_namespace nsp\r\n" + - " ON nsp.oid = connamespace\r\n" + - " WHERE nsp.nspname = :schema\r\n" + - " AND rel.relname = :table"; - - - - Connection connect = getConnection(); - NamedParameterPreparedStatement stmt = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(connect, query); - stmt.setString("table", nameTable); - stmt.setString("schema", schema); - + final Map constraints = new HashMap<>(); + /* + String query = "select conname as constraint_name,contype as constraint_type, " + + " pg_catalog.pg_get_constraintdef(r.oid, true) as ddl " + + "from " + + " pg_class c " + + " join pg_namespace n on n.oid = c.relnamespace " + + " join pg_catalog.pg_constraint r on r.conrelid = c.relfilenode " + + "WHERE " + + " relname = :table and nspname = :schema and c.relkind = 'r'"; + */ + + final String query = + "SELECT " + + " t.tableowner as owner," + + " conname as constraint_name," + + " contype as constraint_type, \r\n" + + " pg_catalog.pg_get_constraintdef(con.oid, true) as ddl\r\n" + + "FROM pg_catalog.pg_constraint con\r\n" + + "INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid\r\n" + + "INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace\r\n" + + "INNER JOIN pg_tables t ON nsp.nspname = t.schemaname AND rel.relname = t.tablename\r\n" + + "WHERE nsp.nspname = :schema\r\n" + + "AND rel.relname = :table"; + + try ( + PreparedStatement stmt = preparedStatement(getConnection(), query, ImmutableMap.of("schema", schema, "table", nameTable)); ResultSet rs = stmt.executeQuery(); + ){ + while(rs.next()){ - DBConstraint con = new DBConstraint(); - con.setName(rs.getString("constraint_name")); - con.setConstraintType(rs.getString("constraint_type")); - con.setSchema(schema); - rowToProperties(rs, con.getOptions()); + final String name = rs.getString("constraint_name"); + final String type = rs.getString("constraint_type"); + final String owner = rs.getString("owner"); + final String ddl = rs.getString("ddl"); + final StringProperties options = new StringProperties(rs); + final DBConstraint con = new DBConstraint(name, options, schema, owner, Collections.emptySet(), ddl, type); + constraints.put(con.getName(), con); } - stmt.close(); - - return constraints; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "constraints").toString()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "constraints").toString(), e); + + return constraints; + + } catch(Exception e) { + String msg = lang.getValue("errors", "adapter", "constraints").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } - + @Override public Map getViews(String schema) { - Map listView = new HashMap(); - try { - String query = - "select nsp.nspname as object_schema, cls.relname as object_name, rol.rolname as owner, \n" + - "'create or replace view ' || nsp.nspname || '.' || cls.relname || ' as ' || pg_get_viewdef(cls.oid) as ddl, (\n" + - " select array_agg(distinct source_ns.nspname || '/' || source_table.relname || '.vw') as dependencySam\n" + - " from pg_depend \n" + - " join pg_rewrite ON pg_depend.objid = pg_rewrite.oid \n" + - " join pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid \n" + - " join pg_class as source_table ON pg_depend.refobjid = source_table.oid AND source_table.relkind = 'v'\n" + - " join pg_attribute ON pg_attribute.attrelid = pg_depend.refobjid \n" + - " and pg_attribute.attnum = pg_depend.refobjsubid \n" + - " join pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace\n" + - " join pg_namespace source_ns ON source_ns.oid = source_table.relnamespace\n" + - " where pg_attribute.attnum > 0 \n" + - " and dependent_view.relname = cls.relname\n" + - ") as dependencies\n" + - "from pg_class cls \n" + - "join pg_roles rol on rol.oid = cls.relowner \n" + - "join pg_namespace nsp on nsp.oid = cls.relnamespace \n" + - "where nsp.nspname not in ('information_schema', 'pg_catalog') \n" + - "and nsp.nspname not like 'pg_toast%' \n" + - "and cls.relkind = 'v' \n" + - "and nsp.nspname = '"+schema+"' \n"; - - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + final Map listView = new HashMap(); + final String query = + "select nsp.nspname as object_schema, cls.relname as object_name, rol.rolname as owner, \n" + + "'create or replace view ' || nsp.nspname || '.' || cls.relname || ' as ' || pg_get_viewdef(cls.oid) as ddl, (\n" + + " select array_agg(distinct source_ns.nspname || '/' || source_table.relname || '.vw') as dependencySam\n" + + " from pg_depend \n" + + " join pg_rewrite ON pg_depend.objid = pg_rewrite.oid \n" + + " join pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid \n" + + " join pg_class as source_table ON pg_depend.refobjid = source_table.oid AND source_table.relkind = 'v'\n" + + " join pg_attribute ON pg_attribute.attrelid = pg_depend.refobjid \n" + + " and pg_attribute.attnum = pg_depend.refobjsubid \n" + + " join pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace\n" + + " join pg_namespace source_ns ON source_ns.oid = source_table.relnamespace\n" + + " where pg_attribute.attnum > 0 \n" + + " and dependent_view.relname = cls.relname\n" + + ") as dependencies\n" + + "from pg_class cls \n" + + "join pg_roles rol on rol.oid = cls.relowner \n" + + "join pg_namespace nsp on nsp.oid = cls.relnamespace \n" + + "where nsp.nspname not in ('information_schema', 'pg_catalog') \n" + + "and cls.relname not in ('pg_buffercache', 'pg_stat_statements') \n" + + "and nsp.nspname not like 'pg_toast%' \n" + + "and cls.relkind = 'v' \n" + + "and nsp.nspname = '"+schema+"' \n"; + + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ while(rs.next()){ - DBView view = new DBView(rs.getString("object_name")); - view.setSchema(rs.getString("object_schema")); - view.setOwner(rs.getString("owner")); - rowToProperties(rs, view.getOptions()); - if(rs.getArray("dependencies") != null){ - view.setDependencies(new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray()))); - } + final String objectName = rs.getString("object_name"); + final String objectSchema = rs.getString("object_schema"); + final String owner = rs.getString("owner"); + final String ddl = rs.getString("ddl"); + final StringProperties options = new StringProperties(rs); + final Set dependencies = rs.getArray("dependencies") == null + ? Collections.emptySet() + : new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())); + + DBView view = new DBView(objectName, options, objectSchema, owner, dependencies, ddl); listView.put(rs.getString("object_name"), view); } - stmt.close(); - return listView; } catch (Exception e) { - logger.error(e.getMessage()); - System.out.println(lang.getValue("errors", "adapter", "views") + ": "+ e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "views") + ": "+ e.getMessage()); + final DBGitLang msg = lang.getValue("errors", "adapter", "views"); + throw new ExceptionDBGitRunTime(msg, e); } + + return listView; } @Override public DBView getView(String schema, String name) { - DBView view = new DBView(name); - view.setSchema(schema); - view.setDependencies(new HashSet<>()); - try { + String query = + "select nsp.nspname as object_schema, cls.relname as object_name, rol.rolname as owner, \n" + + "'create or replace view ' || nsp.nspname || '.' || cls.relname || ' as ' || pg_get_viewdef(cls.oid) as ddl, (\n" + + " select array_agg(distinct source_ns.nspname || '/' || source_table.relname || '.vw') as dependencySam\n" + + " from pg_depend \n" + + " join pg_rewrite ON pg_depend.objid = pg_rewrite.oid \n" + + " join pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid \n" + + " join pg_class as source_table ON pg_depend.refobjid = source_table.oid AND source_table.relkind = 'v'\n" + + " join pg_attribute ON pg_attribute.attrelid = pg_depend.refobjid \n" + + " and pg_attribute.attnum = pg_depend.refobjsubid \n" + + " join pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace\n" + + " join pg_namespace source_ns ON source_ns.oid = source_table.relnamespace\n" + + " where pg_attribute.attnum > 0 \n" + + " and dependent_view.relname = cls.relname\n" + + ") as dependencies\n" + + "from pg_class cls \n" + + "join pg_roles rol on rol.oid = cls.relowner \n" + + "join pg_namespace nsp on nsp.oid = cls.relnamespace \n" + + "where nsp.nspname not in ('information_schema', 'pg_catalog') \n" + + "and nsp.nspname not like 'pg_toast%' \n" + + "and cls.relkind = 'v' \n" + + "and nsp.nspname = '"+schema+"' \n" + + "and cls.relname='"+name+"'\n"; - String query = - "select nsp.nspname as object_schema, cls.relname as object_name, rol.rolname as owner, \n" + - "'create or replace view ' || nsp.nspname || '.' || cls.relname || ' as ' || pg_get_viewdef(cls.oid) as ddl, (\n" + - " select array_agg(distinct source_ns.nspname || '/' || source_table.relname || '.vw') as dependencySam\n" + - " from pg_depend \n" + - " join pg_rewrite ON pg_depend.objid = pg_rewrite.oid \n" + - " join pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid \n" + - " join pg_class as source_table ON pg_depend.refobjid = source_table.oid AND source_table.relkind = 'v'\n" + - " join pg_attribute ON pg_attribute.attrelid = pg_depend.refobjid \n" + - " and pg_attribute.attnum = pg_depend.refobjsubid \n" + - " join pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace\n" + - " join pg_namespace source_ns ON source_ns.oid = source_table.relnamespace\n" + - " where pg_attribute.attnum > 0 \n" + - " and dependent_view.relname = cls.relname\n" + - ") as dependencies\n" + - "from pg_class cls \n" + - "join pg_roles rol on rol.oid = cls.relowner \n" + - "join pg_namespace nsp on nsp.oid = cls.relnamespace \n" + - "where nsp.nspname not in ('information_schema', 'pg_catalog') \n" + - "and nsp.nspname not like 'pg_toast%' \n" + - "and cls.relkind = 'v' \n" + - "and nsp.nspname = '"+schema+"' \n" + - "and cls.relname='"+name+"'\n"; - - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - while (rs.next()) { - view.setOwner(rs.getString("owner")); - if(rs.getArray("dependencies") != null){ - view.setDependencies(new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray()))); - } - rowToProperties(rs, view.getOptions()); - } - stmt.close(); - return view; - - }catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "views") + ": "+ e.getMessage()); - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "views") + ": "+ e.getMessage()); - } + try(Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);){ + + if (rs.next()) { + String owner = rs.getString("owner"); + String ddl = rs.getString("ddl"); + StringProperties options = new StringProperties(rs); + Set dependencies = rs.getArray("dependencies") == null + ? Collections.emptySet() + : new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())); + + return new DBView(name, options, schema, owner, dependencies, ddl); + + } else { + String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); + } + + } catch(Exception e) { + DBGitLang msg = lang.getValue("errors", "adapter", "views"); + throw new ExceptionDBGitRunTime(msg, e); + } } - + @Override public Map getTriggers(String schema) { Map listTrigger = new HashMap(); - try { - String query = "SELECT trg.tgname, tbl.relname as trigger_table ,pg_get_triggerdef(trg.oid) AS ddl \r\n" + - "FROM pg_trigger trg\r\n" + - "JOIN pg_class tbl on trg.tgrelid = tbl.oid\r\n" + - "JOIN pg_namespace ns ON ns.oid = tbl.relnamespace\r\n" + - "and trg.tgconstraint=0 and ns.nspname like \'"+schema+"\'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); + String query = + "SELECT trg.tgname, tbl.relname as trigger_table ,pg_get_triggerdef(trg.oid) AS ddl \r\n" + + "FROM pg_trigger trg\r\n" + + "JOIN pg_class tbl on trg.tgrelid = tbl.oid\r\n" + + "JOIN pg_namespace ns ON ns.oid = tbl.relnamespace\r\n" + + "and trg.tgconstraint=0 and ns.nspname like \'"+schema+"\'"; + + try ( + Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query); + ) { + while(rs.next()){ String name = rs.getString("tgname"); + String owner = "postgres"; String sql = rs.getString("ddl"); - DBTrigger trigger = new DBTrigger(name); - trigger.setSchema(schema); - trigger.setOwner("postgres"); - rowToProperties(rs, trigger.getOptions()); + StringProperties options = new StringProperties(rs); + Set dependencies = Collections.emptySet(); +// rs.getArray("dependencies") == null +// ? Collections.emptySet() +// : new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())); + + DBTrigger trigger = new DBTrigger(name, options, schema, owner, dependencies, sql); listTrigger.put(name, trigger); } - stmt.close(); - return listTrigger; + }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "triggers").toString(), e); + throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "triggers").toString(), e); } + + return listTrigger; } @Override public DBTrigger getTrigger(String schema, String name) { - DBTrigger trigger = null; - try { - String query = "SELECT trg.tgname, tbl.relname as trigger_table ,pg_get_triggerdef(trg.oid) AS ddl \r\n" + - "FROM pg_trigger trg\r\n" + - "JOIN pg_class tbl on trg.tgrelid = tbl.oid\r\n" + - "JOIN pg_namespace ns ON ns.oid = tbl.relnamespace\r\n" + - "and trg.tgconstraint=0 and ns.nspname like \'"+schema+"\' and trg.tgname like \'"+name+"\'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - while(rs.next()){ + String query = + "SELECT trg.tgname, tbl.relname as trigger_table ,pg_get_triggerdef(trg.oid) AS ddl \r\n" + + "FROM pg_trigger trg\r\n" + + "JOIN pg_class tbl on trg.tgrelid = tbl.oid\r\n" + + "JOIN pg_namespace ns ON ns.oid = tbl.relnamespace\r\n" + + "AND trg.tgconstraint=0 and ns.nspname like \'"+schema+"\' and trg.tgname like \'"+name+"\'"; + + try (Statement stmt = getConnection().createStatement();ResultSet rs = stmt.executeQuery(query);){ + + if(rs.next()){ String sql = rs.getString("ddl"); - trigger = new DBTrigger(name); - trigger.setSchema(schema); - trigger.setOwner("postgres"); - rowToProperties(rs, trigger.getOptions()); + String owner = "postgres"; + + StringProperties options = new StringProperties(rs); + Set dependencies = rs.getArray("dependencies") == null + ? Collections.emptySet() + : new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())); + + return new DBTrigger(name, options, schema, owner, dependencies, sql); + + } else { + String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - stmt.close(); - return trigger; - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "triggers").toString(), e); + + } catch(Exception e) { + throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "triggers").toString(), e); } } @Override public Map getPackages(String schema) { - // TODO Auto-generated method stub - return null; + return Collections.emptyMap(); } @Override - public DBPackage getPackage(String schema, String name) { - // TODO Auto-generated method stub - return null; + public DBPackage getPackage(String schema, String name) { + throw new ExceptionDBGitRunTime(new ExceptionDBGitObjectNotFound("cannot get packages on postgres")); + } @Override public Map getProcedures(String schema) { Map mapProcs = new HashMap<>(); - try { - String query = - "SELECT n.nspname AS \"schema\", u.rolname, p.proname AS \"name\", \n" + - " pg_catalog.pg_get_function_arguments(p.oid) AS \"arguments\",\n" + - " pg_get_functiondef(p.oid) AS ddl\n" + - "FROM pg_catalog.pg_proc p\n" + - " JOIN pg_catalog.pg_roles u ON u.oid = p.proowner\n" + - " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" + - "WHERE p.prokind = 'p' \n" + - " AND n.nspname not in('pg_catalog', 'information_schema')\n" + - " AND n.nspname = '"+schema+"'"; - - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + String query = + "SELECT n.nspname AS \"schema\", u.rolname, p.proname AS \"name\", \n" + + " pg_catalog.pg_get_function_arguments(p.oid) AS \"arguments\",\n" + + " pg_get_functiondef(p.oid) AS ddl\n" + + "FROM pg_catalog.pg_proc p\n" + + " JOIN pg_catalog.pg_roles u ON u.oid = p.proowner\n" + + " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" + + ( (getDbVersionNumber() >= 10) + ? "WHERE p.prokind = 'p' \n" + : "WHERE 1=0 \n" + ) + + " AND n.nspname not in('pg_catalog', 'information_schema')\n" + + " AND n.nspname = '"+schema+"'"; + + try (Statement stmt = getConnection().createStatement();ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ String name = rs.getString("name"); String owner = rs.getString("rolname"); - DBProcedure proc = new DBProcedure(name); - proc.setSchema(schema); - proc.setOwner(owner); - rowToProperties(rs,proc.getOptions()); + String sql = rs.getString("ddl"); + StringProperties options = new StringProperties(rs); + Set dependencies = rs.getArray("dependencies") == null + ? Collections.emptySet() + : new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())); - mapProcs.put(mapProcs.containsKey(name) ? name + "_" + proc.getHash() : name, proc); + DBProcedure proc = new DBProcedure(name, options, schema, owner, dependencies, sql); + + String nameInMap = mapProcs.containsKey(name) ? name + "_" + proc.getHash() : name; + mapProcs.put(nameInMap, proc); } - stmt.close(); - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "prc").toString(), e); + + } catch(Exception e) { + String msg = lang.getValue("errors", "adapter", "prc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } + return mapProcs; } @Override public DBProcedure getProcedure(String schema, String name) { - DBProcedure proc = null; - try { - String query = - "SELECT n.nspname AS \"schema\", u.rolname, p.proname AS \"name\", \n" + - " pg_catalog.pg_get_function_arguments(p.oid) AS \"arguments\",\n" + - " pg_get_functiondef(p.oid) AS ddl\n" + - "FROM pg_catalog.pg_proc p\n" + - " JOIN pg_catalog.pg_roles u ON u.oid = p.proowner\n" + - " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" + - "WHERE p.prokind = 'p' \n" + - " AND n.nspname not in('pg_catalog', 'information_schema')\n" + - " AND n.nspname = '"+schema+"'" + - " AND p.proname = '"+name+"'"; - - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); - while(rs.next()){ - proc = new DBProcedure(rs.getString("name")); - proc.setOwner(rs.getString("rolname")); - proc.setSchema(schema); - rowToProperties(rs,proc.getOptions()); + String query = + "SELECT n.nspname AS \"schema\", u.rolname, p.proname AS \"name\", \n" + + " pg_catalog.pg_get_function_arguments(p.oid) AS \"arguments\",\n" + + " pg_get_functiondef(p.oid) AS ddl\n" + + "FROM pg_catalog.pg_proc p\n" + + " JOIN pg_catalog.pg_roles u ON u.oid = p.proowner\n" + + " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" + + ( (getDbVersionNumber() >= 10) + ? "WHERE p.prokind = 'p' \n" + : "WHERE 1=0 \n" + ) + + " AND n.nspname not in('pg_catalog', 'information_schema')\n" + + " AND n.nspname = '"+schema+"'" + + " AND p.proname = '"+name+"'"; + + try (Statement stmt = getConnection().createStatement();ResultSet rs = stmt.executeQuery(query);){ + + if(rs.next()){ + String owner = rs.getString("rolname"); + String sql = rs.getString("ddl"); + StringProperties options = new StringProperties(rs); + Set dependencies = rs.getArray("dependencies") == null + ? Collections.emptySet() + : new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())); + + return new DBProcedure(name, options, schema, owner, dependencies, sql); + + } else { + String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - stmt.close(); - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "prc").toString(), e); + } catch(Exception e) { + String msg = lang.getValue("errors", "adapter", "prc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } - return proc; } @Override public Map getFunctions(String schema) { Map listFunction = new HashMap(); - try { - String query = - "SELECT n.nspname AS \"schema\", u.rolname, p.proname AS \"name\", \n" + - " pg_catalog.pg_get_function_arguments(p.oid) AS \"arguments\",\n" + - " pg_get_functiondef(p.oid) AS ddl\n" + - "FROM pg_catalog.pg_proc p\n" + - " JOIN pg_catalog.pg_roles u ON u.oid = p.proowner\n" + - " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" + - "WHERE p.prokind = 'f' \n" + - " AND n.nspname not in('pg_catalog', 'information_schema')\n" + - " AND n.nspname = '"+schema+"'"; - - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + String query = + "SELECT n.nspname AS \"schema\", u.rolname, p.proname AS \"name\", \n" + + " pg_catalog.pg_get_function_arguments(p.oid) AS \"arguments\",\n" + + " pg_get_functiondef(p.oid) AS ddl\n" + + "FROM pg_catalog.pg_proc p\n" + + " JOIN pg_catalog.pg_roles u ON u.oid = p.proowner\n" + + " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" + + ( (getDbVersionNumber() >= 10) + ? "WHERE p.prokind = 'f' \n" + : "WHERE p.proisagg is false " + )+ + "AND n.nspname not in('pg_catalog', 'information_schema')\n" + + "AND n.nspname = '"+schema+"'"; + + try (Statement stmt = getConnection().createStatement();ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ String name = rs.getString("name"); String owner = rs.getString("rolname"); - String args = rs.getString("arguments"); - DBFunction func = new DBFunction(name); - func.setSchema(schema); - func.setOwner(owner); - rowToProperties(rs,func.getOptions()); - //func.setArguments(args); - - listFunction.put(listFunction.containsKey(name) ? name + "_" + func.getHash() : name, func); + String sql = rs.getString("ddl"); + StringProperties options = new StringProperties(rs); + Set dependencies = Collections.emptySet(); +// rs.getArray("dependencies") == null +// ? Collections.emptySet() +// : new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())); + + DBFunction dbFunction = new DBFunction(name, options, schema, owner, dependencies, sql); + + String nameInMap = listFunction.containsKey(name) ? name + "_" + dbFunction.getHash() : name; + listFunction.put(nameInMap, dbFunction); } - stmt.close(); + }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "fnc").toString(), e); + String msg = lang.getValue("errors", "adapter", "fnc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } return listFunction; } @Override public DBFunction getFunction(String schema, String name) { + String query = + "SELECT n.nspname AS \"schema\", u.rolname, p.proname AS \"name\", \n" + + " pg_catalog.pg_get_function_arguments(p.oid) AS \"arguments\",\n" + + " pg_get_functiondef(p.oid) AS ddl\n" + + "FROM pg_catalog.pg_proc p\n" + + " JOIN pg_catalog.pg_roles u ON u.oid = p.proowner\n" + + " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" + + ( (getDbVersionNumber() >= 10) + ? "WHERE p.prokind = 'f' \n" + : "WHERE 1=1 \n" + ) + + "AND n.nspname not in('pg_catalog', 'information_schema')\n" + + "AND n.nspname = '"+schema+"' AND p.proname = '"+name+"'"; - try { - String query = - "SELECT n.nspname AS \"schema\", u.rolname, p.proname AS \"name\", \n" + - " pg_catalog.pg_get_function_arguments(p.oid) AS \"arguments\",\n" + - " pg_get_functiondef(p.oid) AS ddl\n" + - "FROM pg_catalog.pg_proc p\n" + - " JOIN pg_catalog.pg_roles u ON u.oid = p.proowner\n" + - " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" + - "WHERE p.prokind = 'f' \n" + - " AND n.nspname not in('pg_catalog', 'information_schema')\n" + - " AND n.nspname = '"+schema+"' AND p.proname = '"+name+"'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + try (Statement stmt = getConnection().createStatement();ResultSet rs = stmt.executeQuery(query);){ - DBFunction func = null; - while (rs.next()) { - func = new DBFunction(rs.getString("name")); + + if (rs.next()) { String owner = rs.getString("rolname"); - String args = rs.getString("arguments"); - func.setSchema(schema); - func.setOwner(owner); + String sql = rs.getString("ddl"); + StringProperties options = new StringProperties(rs); + Set dependencies = rs.getArray("dependencies") == null + ? Collections.emptySet() + : new HashSet<>(Arrays.asList((String[])rs.getArray("dependencies").getArray())); + + return new DBFunction(name, options, schema, owner, dependencies, sql); + //String args = rs.getString("arguments"); //func.setArguments(args); - rowToProperties(rs,func.getOptions()); + + } else { + String msg = lang.getValue("errors", "adapter", "objectNotFoundInDb").toString(); + throw new ExceptionDBGitObjectNotFound(msg); } - stmt.close(); - - return func; - - }catch(Exception e) { - throw new ExceptionDBGitRunTime(lang.getValue("errors", "adapter", "fnc").toString(), e); + + + } catch(Exception e) { + String msg = lang.getValue("errors", "adapter", "fnc").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public DBTableData getTableDataPortion(String schema, String nameTable, int portionIndex, int tryNumber) { - DBTableData data = new DBTableData(); - + final DBGitConfig config = DBGitConfig.getInstance(); try { - int maxRowsCount = DBGitConfig.getInstance().getInteger("core", "MAX_ROW_COUNT_FETCH", DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH)); - - if (DBGitConfig.getInstance().getBoolean("core", "LIMIT_FETCH", DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true))) { - Statement st = getConnection().createStatement(); - String query = "select COALESCE(count(*), 0) kolvo from ( select 1 from "+ - DBAdapterPostgres.escapeNameIfNeeded(schema) + "." + DBAdapterPostgres.escapeNameIfNeeded(nameTable) + " limit " + (maxRowsCount + 1) + " ) tbl"; - ResultSet rs = st.executeQuery(query); - rs.next(); - if (rs.getInt("kolvo") > maxRowsCount) { - data.setErrorFlag(DBTableData.ERROR_LIMIT_ROWS); - return data; + final boolean isFetchLimitedDefault = config.getBooleanGlobal("core", "LIMIT_FETCH", true); + final boolean isFetchLimited = config.getBoolean("core", "LIMIT_FETCH", isFetchLimitedDefault); + final int maxRowsCountDefault = config.getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH); + final int maxRowsCount = config.getInteger("core", "MAX_ROW_COUNT_FETCH", maxRowsCountDefault); + final int portionSize = config.getInteger("core", "PORTION_SIZE", config.getIntegerGlobal("core", "PORTION_SIZE", 1000)); + final int portionBegin = 1 + portionSize*portionIndex; + final int portionEnd = portionSize + portionSize*portionIndex; + + final String tableRowsCountQuery = + "select COALESCE(count(*), 0) kolvo " + + "from ( " + + " select 1 from " + escapeNameIfNeeded(schema) + "." + escapeNameIfNeeded(nameTable) + + " limit " + (maxRowsCount + 1) + " " + + ") tbl"; + + final String dataQuery = + " SELECT * FROM \r\n" + + " (SELECT f.*, ROW_NUMBER() OVER (ORDER BY ctid) DBGIT_ROW_NUM FROM " + escapeNameIfNeeded(schema) + "." + escapeNameIfNeeded(nameTable) + " f) s\r\n" + + " WHERE DBGIT_ROW_NUM BETWEEN " + portionBegin + " and " + portionEnd; + + + if (isFetchLimited) { + try(Statement st = getConnection().createStatement(); ResultSet rs = st.executeQuery(tableRowsCountQuery);){ + if(!rs.next()) { + String msg = "error fetch table rows count"; + throw new ExceptionDBGitRunTime(msg); + } else if (rs.getInt("kolvo") > maxRowsCount) { + return new DBTableData(DBTableData.ERROR_LIMIT_ROWS); + } } + } - int portionSize = DBGitConfig.getInstance().getInteger("core", "PORTION_SIZE", DBGitConfig.getInstance().getIntegerGlobal("core", "PORTION_SIZE", 1000)); - - int begin = 1 + portionSize*portionIndex; - int end = portionSize + portionSize*portionIndex; - - Statement st = getConnection().createStatement(); - String query = " SELECT * FROM \r\n" + - " (SELECT f.*, ROW_NUMBER() OVER (ORDER BY ctid) DBGIT_ROW_NUM FROM " + DBAdapterPostgres.escapeNameIfNeeded(schema) + "." + DBAdapterPostgres.escapeNameIfNeeded(nameTable) + " f) s\r\n" + - " WHERE DBGIT_ROW_NUM BETWEEN " + begin + " and " + end; - ResultSet rs = st.executeQuery(query); - - data.setResultSet(rs); - return data; + return new DBTableData(getConnection(), dataQuery); + + } catch(Exception e) { - ConsoleWriter.println("err: " + e.getLocalizedMessage()); - + + final int maxTriesCount = DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000)); + final int tryDelay = DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000)); + + ConsoleWriter.println(e.getLocalizedMessage(), messageLevel); + ConsoleWriter.detailsPrintln(ExceptionUtils.getStackTrace(e), messageLevel); logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - - try { - if (tryNumber <= DBGitConfig.getInstance().getInteger("core", "TRY_COUNT", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_COUNT", 1000))) { - try { - TimeUnit.SECONDS.sleep(DBGitConfig.getInstance().getInteger("core", "TRY_DELAY", DBGitConfig.getInstance().getIntegerGlobal("core", "TRY_DELAY", 1000))); - } catch (InterruptedException e1) { - throw new ExceptionDBGitRunTime(e1.getMessage()); - } - ConsoleWriter.println("Error while getting portion of data, try " + tryNumber); - getTableDataPortion(schema, nameTable, portionIndex, tryNumber++); + + if (tryNumber <= maxTriesCount) { + + final String waitMessage = DBGitLang.getInstance() + .getValue("errors", "dataTable", "wait") + .withParams(String.valueOf(tryDelay)); + + final String tryAgainMessage = DBGitLang.getInstance() + .getValue("errors", "dataTable", "tryAgain") + .withParams(String.valueOf(tryNumber)); + + ConsoleWriter.println(waitMessage, messageLevel); + try { TimeUnit.SECONDS.sleep(tryDelay); } catch (InterruptedException e1) { + throw new ExceptionDBGitRunTime(e1.getMessage()); } - } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - try { - getConnection().rollback(); - } catch (Exception e2) { - logger.error(lang.getValue("errors", "adapter", "rollback").toString(), e2); + + ConsoleWriter.println(tryAgainMessage, messageLevel); + return getTableDataPortion(schema, nameTable, portionIndex, tryNumber++); + + } else { + final String msg = DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); } - throw new ExceptionDBGitRunTime(e.getMessage()); } - } - + } + @Override public DBTableData getTableData(String schema, String nameTable) { - String tableName = DBAdapterPostgres.escapeNameIfNeeded(schema)+"."+ DBAdapterPostgres.escapeNameIfNeeded(nameTable); + final String tableName = escapeNameIfNeeded(schema)+"."+ escapeNameIfNeeded(nameTable); + final int maxRowsCount = DBGitConfig.getInstance().getInteger("core", "MAX_ROW_COUNT_FETCH", DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH)); + final Boolean isFetchLimited = DBGitConfig.getInstance().getBoolean("core", "LIMIT_FETCH", DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true)); try { - DBTableData data = new DBTableData(); - - int maxRowsCount = DBGitConfig.getInstance().getInteger("core", "MAX_ROW_COUNT_FETCH", DBGitConfig.getInstance().getIntegerGlobal("core", "MAX_ROW_COUNT_FETCH", MAX_ROW_COUNT_FETCH)); - - if (DBGitConfig.getInstance().getBoolean("core", "LIMIT_FETCH", DBGitConfig.getInstance().getBooleanGlobal("core", "LIMIT_FETCH", true))) { - Statement st = getConnection().createStatement(); - String query = "select COALESCE(count(*), 0) kolvo from ( select 1 from "+ - tableName + " limit " + (maxRowsCount + 1) + " ) tbl"; - ResultSet rs = st.executeQuery(query); - rs.next(); - if (rs.getInt("kolvo") > maxRowsCount) { - data.setErrorFlag(DBTableData.ERROR_LIMIT_ROWS); - return data; + if (isFetchLimited) { + + String query = + "select COALESCE(count(*), 0) kolvo " + + "from ( " + + " select 1 from "+ tableName + + " limit " + (maxRowsCount + 1) + + " ) tbl"; + + try(Statement st = getConnection().createStatement(); ResultSet rs = st.executeQuery(query);){ + if(!rs.next()) throw new ExceptionDBGitRunTime("Could not execute rows count query"); + if (rs.getInt("kolvo") > maxRowsCount) { + return new DBTableData(DBTableData.ERROR_LIMIT_ROWS); + } } - } - Statement st = getConnection().createStatement(); - ResultSet rs = st.executeQuery("select * from "+tableName); - data.setResultSet(rs); - + } + + final String tdQuery = "select * from " + tableName; + return new DBTableData(getConnection(), tdQuery); //TODO other state - - return data; + //TODO find out what does 'other state' todo comment mean... + } catch(Exception e) { - logger.error(lang.getValue("errors", "adapter", "tableData").toString(), e); - try { - getConnection().rollback(); - } catch (Exception e2) { - logger.error(lang.getValue("errors", "adapter", "rollback").toString(), e2); - } - throw new ExceptionDBGitRunTime(e.getMessage()); + final String msg = DBGitLang.getInstance().getValue("errors", "adapter", "tableData").toString(); + throw new ExceptionDBGitRunTime(msg, e); } } @Override public Map getUsers() { Map listUser = new HashMap(); - try { - String query = "select *from pg_user"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + String query = "select * from pg_user"; + try (Statement stmt = getConnection().createStatement();ResultSet rs = stmt.executeQuery(query);){ + while(rs.next()){ String name = rs.getString(1); - DBUser user = new DBUser(name); + StringProperties options = new StringProperties(rs); + + DBUser user = new DBUser(name, options); listUser.put(name, user); } - stmt.close(); - }catch(Exception e) { - logger.error(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); + } catch(Exception e) { + throw new ExceptionDBGitRunTime(e); } - //connect.cre //select *from pg_catalog.pg_namespace; return listUser; } @@ -907,121 +982,341 @@ public Map getUsers() { @Override public Map getRoles() { Map listRole = new HashMap(); - try { - String query = "select *,array_to_string(array(SELECT rolname " + - "FROM pg_roles,pg_auth_members " + - "WHERE member = auth.oid and roleid=oid), ', ') as rolmemberof from pg_authid as auth where auth.rolname not like 'pg_%'"; - Connection connect = getConnection(); - Statement stmt = connect.createStatement(); - ResultSet rs = stmt.executeQuery(query); + String query = + "SELECT r.rolname, r.rolsuper, r.rolinherit,\n" + + " r.rolcreaterole, r.rolcreatedb, r.rolcanlogin, \n" + + " r.rolreplication," + ((getDbVersionNumber() > 9.5) ? "r.rolbypassrls,\n" : "\n") + + " r.rolconnlimit, r.rolpassword, r.rolvaliduntil,\n" + + " ARRAY(SELECT b.rolname\n" + + " FROM pg_catalog.pg_auth_members m\n" + + " JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n" + + " WHERE m.member = r.oid) as memberof\n" + + "FROM pg_catalog.pg_roles r\n" + + "WHERE r.rolname !~ '^pg_'\n" + + "ORDER BY 1;"; + try (Statement stmt = getConnection().createStatement(); ResultSet rs = stmt.executeQuery(query);) { + while(rs.next()){ - String name = rs.getString("rolname"); - DBRole role = new DBRole(name); - rowToProperties(rs, role.getOptions()); - listRole.put(name, role); + String name = rs.getString("rolname"); + StringProperties options = new StringProperties(rs); + + DBRole role = new DBRole(name, options); + listRole.put(name, role); } - stmt.close(); - }catch(Exception e) { - logger.error(e.getMessage()); - throw new ExceptionDBGitRunTime(e.getMessage()); + + } catch(Exception e) { + throw new ExceptionDBGitRunTime(e); } + return listRole; } @Override - public boolean userHasRightsToGetDdlOfOtherUsers() { - return true; + 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 IFactoryDBBackupAdapter getBackupAdapterFactory() { - return backupFactory; + 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 DbType getDbType() { - return DbType.POSTGRES; + 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 String getDbVersion() { - try { - PreparedStatement stmt = getConnection().prepareStatement("SHOW server_version"); - ResultSet resultSet = stmt.executeQuery(); - resultSet.next(); - - String result = resultSet.getString("server_version"); - resultSet.close(); - stmt.close(); - - return result; - } catch (SQLException e) { - return ""; + 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 IFactoryDBConvertAdapter getConvertAdapterFactory() { - return convertFactory; + 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 void createSchemaIfNeed(String schemaName) throws ExceptionDBGit { - try { - Statement st = connect.createStatement(); - ResultSet rs = st.executeQuery("select count(*) cnt from information_schema.schemata where upper(schema_name) = '" + - schemaName.toUpperCase() + "'"); - - rs.next(); - if (rs.getInt("cnt") == 0) { - StatementLogging stLog = new StatementLogging(connect, getStreamOutputSqlCommand(), isExecSql()); - stLog.execute("create schema " + schemaName + ";\n"); + 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()); + } + } - stLog.close(); + @Override + public boolean userHasRightsToGetDdlOfOtherUsers() { return true; } + @Override + public IFactoryDBBackupAdapter getBackupAdapterFactory() { return backupFactory; } + @Override + public IFactoryDBConvertAdapter getConvertAdapterFactory() { return convertFactory; } + @Override + public DbType getDbType() { return DbType.POSTGRES; } + @Override + public String getDbVersion() { + final String query = "SHOW server_version"; + try ( + PreparedStatement stmt = getConnection().prepareStatement(query); + ResultSet resultSet = stmt.executeQuery(); + ) { + + if(!resultSet.next()){ + final String msg = "failed to get schema data"; + throw new ExceptionDBGitRunTime(msg); } - rs.close(); - st.close(); + return resultSet.getString("server_version"); + } catch (SQLException e) { - throw new ExceptionDBGit(lang.getValue("errors", "adapter", "createSchema") + ": " + e.getLocalizedMessage()); + final String msg = "failed to get database version"; + throw new ExceptionDBGitRunTime(msg, e); } - } + @Override + public String getDefaultScheme() throws ExceptionDBGit { return "public"; } + @Override + public boolean isReservedWord(String word) { return reservedWords.contains(word.toUpperCase()); } @Override - public void createRoleIfNeed(String roleName) throws ExceptionDBGit { - try { - Statement st = connect.createStatement(); - ResultSet rs = st.executeQuery("select count(*) cnt from pg_catalog.pg_roles where upper(rolname) = '" + - roleName.toUpperCase() + "'"); - - rs.next(); + public void createSchemaIfNeed(String schemaName) { + final String query = + "select count(*) cnt " + + "from information_schema.schemata " + + "where upper(schema_name) = '" + schemaName.toUpperCase() + "'"; + + try (Statement st = connect.createStatement(); ResultSet rs = st.executeQuery(query);){ + + if(!rs.next()) { + final String msg = "failed to get schema data"; + throw new ExceptionDBGitRunTime(msg); + } + if (rs.getInt("cnt") == 0) { - StatementLogging stLog = new StatementLogging(connect, getStreamOutputSqlCommand(), isExecSql()); - stLog.execute("CREATE ROLE " + roleName + " LOGIN PASSWORD '" + roleName + "'"); - - stLog.close(); + try(StatementLogging stLog = new StatementLogging(connect, getStreamOutputSqlCommand(), isExecSql());){ + stLog.execute("create schema " + schemaName + ";\n"); + } + } else { + return; } - - rs.close(); - st.close(); - } catch (SQLException e) { - throw new ExceptionDBGit(lang.getValue("errors", "adapter", "createSchema") + ": " + e.getLocalizedMessage()); - } - } - @Override - public String getDefaultScheme() throws ExceptionDBGit { - return "public"; + } catch (SQLException e) { + final String msg = lang.getValue("errors", "adapter", "createSchema").toString(); + throw new ExceptionDBGitRunTime(msg, e); + } + } @Override - public boolean isReservedWord(String word) { - return reservedWords.contains(word.toUpperCase()); - } + public void createRoleIfNeed(String roleName) { + final String query = + "select count(*) cnt " + + "from pg_catalog.pg_roles " + + "where upper(rolname) = '" + roleName.toUpperCase() + "'"; + try (Statement st = connect.createStatement(); ResultSet rs = st.executeQuery(query);) { + + if(!rs.next()) { + final String msg = "failed to get role data"; + throw new ExceptionDBGitRunTime(msg); + } + + if (rs.getInt("cnt") == 0){ + try(StatementLogging stLog = new StatementLogging(connect, getStreamOutputSqlCommand(), isExecSql());) { + //TODO which kind of PASSWORD that equals to ROLE NAME? + stLog.execute("CREATE ROLE " + roleName + " LOGIN PASSWORD '" + roleName + "'"); + } + } else { + return; + } + + } catch (SQLException e) { + final DBGitLang msg = lang.getValue("errors", "adapter", "createSchema"); + throw new ExceptionDBGitRunTime(msg, e); + } + } - public static String escapeNameIfNeeded(String name){ + public String escapeNameIfNeeded(String name){ boolean shouldBeEscaped = !name.equals(name.toLowerCase()) || name.contains(".") || name.contains(".") @@ -1659,4 +1954,4 @@ public static String escapeNameIfNeeded(String name){ reservedWords.add("YEAR"); reservedWords.add("ZONE"); } -} \ No newline at end of file +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBBackupAdapterPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBBackupAdapterPostgres.java index d14695f..faac3af 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBBackupAdapterPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBBackupAdapterPostgres.java @@ -39,7 +39,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio createSchema(stLog, schema); } - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); //dropIfExists(isSaveToSchema() ? PREFIX + schema : schema, // isSaveToSchema() ? objectName : PREFIX + objectName, stLog); @@ -54,7 +54,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio if (file.exists()) obj = metaSql.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else if (obj instanceof MetaTable) { @@ -68,41 +68,44 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio String tableSamRe = schema + "\\.\\\"?" + Pattern.quote(tableName) + "\\\"?"; if(!isExists(schema, tableName)) { + //so don't actually backup, as I see... File file = new File(DBGitPath.getFullPath() + metaTable.getFileName()); if (file.exists()) obj = metaTable.loadFromFile(); return obj; } - if (isSaveToSchema()) { - createSchema(stLog, schema); - } + if (isSaveToSchema()) { createSchema(stLog, schema); } - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(tableName, getFullDbName(schema, tableName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(tableName, getFullDbName(schema, tableName)), messageLevel); - StringBuilder tableDdlSb = new StringBuilder(MessageFormat.format( - "create table {0} as (select * from {1}.{2} where 1={3}) {4};\n alter table {0} owner to {5};\n" + "create table {0} as (select * from {1}.{2} where 1={3}) {4};" , backupTableSam - , DBAdapterPostgres.escapeNameIfNeeded(schema) - , DBAdapterPostgres.escapeNameIfNeeded(tableName) - , isToSaveData() ? "1" : "0" + , adapter.escapeNameIfNeeded(schema) + , adapter.escapeNameIfNeeded(tableName) + , isToSaveData() ? "1" : "0" //TableData , metaTable.getTable().getOptions().getChildren().containsKey("tablespace") ? " tablespace " + metaTable.getTable().getOptions().get("tablespace").getData() : "" , metaTable.getTable().getOptions().get("owner").getData() )); + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + String owner = metaTable.getTable().getOptions().get("owner").getData(); + tableDdlSb.append(MessageFormat.format("\nalter table {0} owner to \"{1}\";\n", backupTableSam, owner)); + } + Map fkRefReplaces = new HashMap<>(); for (String fk : metaTable.getTable().getDependencies()){ String fkname = fk.substring(fk.indexOf('/')+1,fk.lastIndexOf('.')) ; String fkschema = fk.substring(0,fk.indexOf('/')) ; - String nameDb = "("+fkschema+ "\\.)?" + "\\\"?" + Pattern.quote(DBAdapterPostgres.escapeNameIfNeeded(fkname)) + "\\\"?(?=\\()"; + String nameDb = "("+fkschema+ "\\.)?" + "\\\"?" + Pattern.quote(adapter.escapeNameIfNeeded(fkname)) + "\\\"?(?=\\()"; String nameReplacement = isSaveToSchema() - ? Matcher.quoteReplacement(DBAdapterPostgres.escapeNameIfNeeded(PREFIX+fkschema) + "." + fkname) - : Matcher.quoteReplacement(fkschema + "." + DBAdapterPostgres.escapeNameIfNeeded(PREFIX+fkname)); + ? Matcher.quoteReplacement(adapter.escapeNameIfNeeded(PREFIX+fkschema) + "." + fkname) + : Matcher.quoteReplacement(fkschema + "." + adapter.escapeNameIfNeeded(PREFIX+fkname)); fkRefReplaces.put(nameDb, nameReplacement); } @@ -110,7 +113,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio for (DBIndex index : metaTable.getIndexes().values()) { String indexName = index.getName(); String indexNameRe = "\\\"?" + Pattern.quote(indexName) + "\\\"?"; - String backupIndexNameRe = Matcher.quoteReplacement(DBAdapterPostgres.escapeNameIfNeeded( + String backupIndexNameRe = Matcher.quoteReplacement(adapter.escapeNameIfNeeded( PREFIX + indexName + ((metaTable.getConstraints().containsKey(index.getName())) ? "_idx" : "") )); @@ -128,10 +131,10 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio } for (DBConstraint constraint : metaTable.getConstraints().values().stream().sorted(Comparator.comparing(x->!x.getName().toLowerCase().contains("pk"))).collect(Collectors.toList())) { - String name = DBAdapterPostgres.escapeNameIfNeeded(PREFIX + constraint.getName()); + String name = adapter.escapeNameIfNeeded(PREFIX + constraint.getName()); String constrName = constraint.getName(); String constrNameRe = "\\\"?" + Pattern.quote(constrName) + "\\\"?"; - String backupConstrNameRe = Matcher.quoteReplacement(DBAdapterPostgres.escapeNameIfNeeded(PREFIX + constrName)); + String backupConstrNameRe = Matcher.quoteReplacement(adapter.escapeNameIfNeeded(PREFIX + constrName)); String constrDef = constraint.getSql().replaceAll(constrNameRe, backupConstrNameRe); for(String reference : fkRefReplaces.keySet()){ constrDef = constrDef.replaceAll(reference, fkRefReplaces.get(reference)); } @@ -153,7 +156,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio File file = new File(DBGitPath.getFullPath() + metaTable.getFileName()); if (file.exists()) obj = metaTable.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else if (obj instanceof MetaSequence) { MetaSequence metaSequence = (MetaSequence) obj; metaSequence.loadFromDB(); @@ -167,7 +170,7 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio String sequenceName = getFullDbName(schema, objectName); - ConsoleWriter.detailsPrint(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "tryingToCopy").withParams(objectName, getFullDbName(schema, objectName)), messageLevel); String ddl = "create sequence " + sequenceName + "\n" + (metaSequence.getSequence().getOptions().get("cycle_option").toString().equals("YES") ? "CYCLE\n" : "") @@ -175,8 +178,10 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio + " START " + metaSequence.getSequence().getOptions().get("start_value").toString() + "\n" + " MINVALUE " + metaSequence.getSequence().getOptions().get("minimum_value").toString() + "\n" + " MAXVALUE " + metaSequence.getSequence().getOptions().get("maximum_value").toString() + ";\n"; - - ddl += "alter sequence "+ sequenceName + " owner to "+ metaSequence.getSequence().getOptions().get("owner").getData()+";\n"; + + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + ddl += "alter sequence "+ sequenceName + " owner to \""+ metaSequence.getSequence().getOptions().get("owner").getData()+"\";\n"; + } dropIfExists( isSaveToSchema() ? PREFIX + schema : schema, @@ -188,15 +193,15 @@ public IMetaObject backupDBObject(IMetaObject obj) throws SQLException, Exceptio File file = new File(DBGitPath.getFullPath() + metaSequence.getFileName()); if (file.exists()) obj = metaSequence.loadFromFile(); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } } catch (SQLException e1) { - throw new ExceptionDBGit(lang.getValue("errors", "backup", "backupError"). - withParams(obj.getName() + ": " + e1.getLocalizedMessage())); + throw new ExceptionDBGit( + lang.getValue("errors", "backup", "backupError").withParams(obj.getName()) + , e1 + ); } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - connection.rollback(); throw new ExceptionDBGitRestore(lang.getValue("errors", "backup", "backupError").withParams(obj.getName()), e); } finally { stLog.close(); @@ -212,10 +217,10 @@ public void restoreDBObject(IMetaObject obj) throws Exception { private String getFullDbName(String schema, String objectName) { if (isSaveToSchema()){ - return DBAdapterPostgres.escapeNameIfNeeded(PREFIX + schema) + "." + DBAdapterPostgres.escapeNameIfNeeded(objectName); + return adapter.escapeNameIfNeeded(PREFIX + schema) + "." + adapter.escapeNameIfNeeded(objectName); } else { - return DBAdapterPostgres.escapeNameIfNeeded(schema) + "." + DBAdapterPostgres.escapeNameIfNeeded(PREFIX + objectName); + return adapter.escapeNameIfNeeded(schema) + "." + adapter.escapeNameIfNeeded(PREFIX + objectName); } } @@ -232,7 +237,7 @@ public void dropIfExists(String owner, String objectName, StatementLogging stLog "where sch = '" + owner.toLowerCase() + "' and obj_name = '"+objectName+"'"); while (rs.next()) { - stLog.execute("drop " + rs.getString("tp") + " " + DBAdapterPostgres.escapeNameIfNeeded(owner) + "." + DBAdapterPostgres.escapeNameIfNeeded(objectName)); + stLog.execute("drop " + rs.getString("tp") + " " + adapter.escapeNameIfNeeded(owner) + "." + adapter.escapeNameIfNeeded(objectName)); } rs.close(); @@ -262,8 +267,8 @@ public void dropIfExists(IMetaObject imo, StatementLogging stLog) throws Excepti while (rs.next()) { stLog.execute(MessageFormat.format("DROP {0} {1}.{2}", rs.getString("tp"), - DBAdapterPostgres.escapeNameIfNeeded(nm.getSchema()), - DBAdapterPostgres.escapeNameIfNeeded(nm.getName()) + adapter.escapeNameIfNeeded(nm.getSchema()), + adapter.escapeNameIfNeeded(nm.getName()) )); } @@ -301,8 +306,8 @@ public boolean createSchema(StatementLogging stLog, String schema) { rs.next(); if (rs.getInt("cnt") == 0) { - ConsoleWriter.detailsPrintLn(lang.getValue("general", "backup", "creatingSchema").withParams(PREFIX + schema)); - stLog.execute("create schema " + DBAdapterPostgres.escapeNameIfNeeded(PREFIX + schema)); + ConsoleWriter.detailsPrintln(lang.getValue("general", "backup", "creatingSchema").withParams(PREFIX + schema), messageLevel); + stLog.execute("create schema " + adapter.escapeNameIfNeeded(PREFIX + schema)); } rs.close(); @@ -311,7 +316,10 @@ public boolean createSchema(StatementLogging stLog, String schema) { return true; } catch (SQLException e) { - ConsoleWriter.println(lang.getValue("errors", "backup", "cannotCreateSchema").withParams(e.getLocalizedMessage())); + ConsoleWriter.println(lang.getValue("errors", "backup", "cannotCreateSchema") + .withParams(e.getLocalizedMessage()) + , messageLevel + ); return false; } } 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/DBRestoreFunctionPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreFunctionPostgres.java index 1270e75..6d1c3ee 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreFunctionPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreFunctionPostgres.java @@ -1,108 +1,101 @@ -package ru.fusionsoft.dbgit.postgres; - -import java.sql.Connection; -import java.util.Map; - -import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.dbobjects.DBFunction; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaFunction; -import ru.fusionsoft.dbgit.statement.StatementLogging; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class DBRestoreFunctionPostgres extends DBRestoreAdapter { - - @Override - public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreFnc").withParams(obj.getName()), 1); - try { - if (obj instanceof MetaFunction) { - MetaFunction restoreFunction = (MetaFunction)obj; - String restoreFunctionName = DBAdapterPostgres.escapeNameIfNeeded(restoreFunction.getSqlObject().getName()); - Map functions = adapter.getFunctions(restoreFunction.getSqlObject().getSchema()); - boolean exist = false; - if(!(functions.isEmpty() || functions == null)) { - for(DBFunction fnc:functions.values()) { - if(restoreFunctionName.equals(DBAdapterPostgres.escapeNameIfNeeded(fnc.getName()))){ - exist = true; - - //if codes differ - if( !restoreFunction.getSqlObject().getSql() - .replace(" ", "") - .equals(fnc.getSql().replace(" ", "")) - ) { - st.execute(restoreFunction.getSqlObject().getSql()); - } - - //if owners differ - if(!restoreFunction.getSqlObject().getOwner().equals(fnc.getOwner())) { - //without arguments - if(restoreFunction.getSqlObject().getOptions().get("arguments").getData() == null || restoreFunction.getSqlObject().getOptions().get("arguments").getData().isEmpty()) { - st.execute( - "ALTER FUNCTION "+ restoreFunctionName + "() OWNER TO " - + restoreFunction.getSqlObject().getOwner()) - ; - } - //with arguments - else { - st.execute( - "ALTER FUNCTION "+restoreFunctionName +"(" - + restoreFunction.getSqlObject().getOptions().get("arguments").getData() - + ") OWNER TO " + restoreFunction.getSqlObject().getOwner() - ); - } - } - //TODO Восстановление привилегий - } - } - } - if(!exist){ - st.execute(restoreFunction.getSqlObject().getSql()); - //TODO Восстановление привилегий - } - } - else - { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.detailsPrintlnRed(e.getLocalizedMessage()); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - st.close(); - } - return true; - } - - @Override - public void removeMetaObject(IMetaObject obj) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - - try { - if(! (obj instanceof MetaFunction)) throw new ExceptionDBGit("Wrong IMetaObject type, expected: fnc, was: " + obj.getType().getValue()); - MetaFunction fncMeta = (MetaFunction) obj; - DBFunction fnc = (DBFunction) fncMeta.getSqlObject(); - if (fnc == null) return; - - String schema = getPhisicalSchema(fnc.getSchema()); - st.execute("DROP FUNCTION "+DBAdapterPostgres.escapeNameIfNeeded(schema)+"."+DBAdapterPostgres.escapeNameIfNeeded(fnc.getName())); - } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); - } finally { - st.close(); - } - } - -} +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.ExceptionDBGit; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; +import ru.fusionsoft.dbgit.dbobjects.DBFunction; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaFunction; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; +import ru.fusionsoft.dbgit.utils.StringProperties; + +public class DBRestoreFunctionPostgres extends DBRestoreAdapter { + + @Override + public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + try(StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql());) { + if (obj instanceof MetaFunction) { + + MetaFunction restoreFunction = (MetaFunction)obj; + String restoreFunctionName = restoreFunction.getSqlObject().getName(); + Map functions = adapter.getFunctions(restoreFunction.getSqlObject().getSchema()); + boolean exist = false; + if(!(functions.isEmpty() || functions == null)) { + for(DBFunction fnc:functions.values()) { + if(restoreFunctionName.equals(fnc.getName())){ + exist = true; + + //if codes differ + if( !restoreFunction.getSqlObject().getSql() + .replace(" ", "") + .equals(fnc.getSql().replace(" ", "")) + ) { + st.execute(restoreFunction.getSqlObject().getSql()); + } + + //if owners differ + if(!restoreFunction.getSqlObject().getOwner().equals(fnc.getOwner())) { + StringProperties restoreProcArgs = restoreFunction.getSqlObject().getOptions().get("arguments"); + String args = restoreProcArgs != null ? restoreProcArgs.getData().replaceAll("(\\w+ \\w+) (DEFAULT [^\\,\\n]+)(\\,|\\b)", "$1") : ""; + + st.execute(MessageFormat.format("ALTER FUNCTION {0}.{1}({2}) OWNER TO \"{3}\"" + , restoreFunction.getUnderlyingDbObject().getSchema() + , adapter.escapeNameIfNeeded(restoreFunctionName) + , args + , restoreFunction.getSqlObject().getOwner()) + ); + } + //TODO Восстановление привилегий + } + } + } + if(!exist){ + st.execute(restoreFunction.getSqlObject().getSql()); + //TODO Восстановление привилегий + } + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "function", obj.getType().getValue() + )); + } + } 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(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + + try { + if(! (obj instanceof MetaFunction)) throw new ExceptionDBGit("Wrong IMetaObject type, expected: fnc, was: " + obj.getType().getValue()); + MetaFunction fncMeta = (MetaFunction) obj; + DBFunction fnc = (DBFunction) fncMeta.getSqlObject(); + if (fnc == null) return; + + String schema = getPhisicalSchema(fnc.getSchema()); + st.execute("DROP FUNCTION "+adapter.escapeNameIfNeeded(schema)+"."+adapter.escapeNameIfNeeded(fnc.getName())); + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); + } finally { + st.close(); + } + } + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreProcedurePostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreProcedurePostgres.java index 2316c2f..a8edf38 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreProcedurePostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreProcedurePostgres.java @@ -1,113 +1,105 @@ -package ru.fusionsoft.dbgit.postgres; - -import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.dbobjects.DBProcedure; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaProcedure; -import ru.fusionsoft.dbgit.meta.NameMeta; -import ru.fusionsoft.dbgit.statement.StatementLogging; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -import java.sql.Connection; -import java.text.MessageFormat; -import java.util.Map; - -public class DBRestoreProcedurePostgres extends DBRestoreAdapter { - - @Override - public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restorePrc").withParams(obj.getName()), 1); - try { - if (obj instanceof MetaProcedure) { - MetaProcedure restoreProc = (MetaProcedure)obj; - NameMeta nm = new NameMeta(restoreProc); - String restoreProcName = DBAdapterPostgres.escapeNameIfNeeded(nm.getName()); - Map procs = adapter.getProcedures(nm.getSchema()); - boolean exist = false; - if(!(procs.isEmpty() || procs == null)) { - for(DBProcedure prc : procs.values()) { - if(restoreProcName.equals(DBAdapterPostgres.escapeNameIfNeeded(prc.getName()))){ - exist = true; - - //if codes differ - if( !restoreProc.getSqlObject().getSql() - .replaceAll("\\s+", "") - .equals(prc.getSql().replaceAll("\\s+", "")) - ) { - st.execute(restoreProc.getSqlObject().getSql()); - } - - //if owners differ - if(!restoreProc.getSqlObject().getOwner().equals(prc.getOwner())) { - //without arguments - if( restoreProc.getSqlObject().getOptions().get("arguments").getData() == null || - restoreProc.getSqlObject().getOptions().get("arguments").getData().isEmpty() - ) { - st.execute(MessageFormat.format("ALTER PROCEDURE {0}() OWNER TO {2}" - , restoreProcName - , restoreProc.getSqlObject().getOwner())); - } - //with arguments - else { - st.execute(MessageFormat.format("ALTER PROCEDURE {0}({1}) OWNER TO {2}" - , restoreProcName - , restoreProc.getSqlObject().getOptions().get("arguments").getData() - , restoreProc.getSqlObject().getOwner())); - } - } - //TODO Восстановление привилегий - } - } - } - if(!exist){ - st.execute(restoreProc.getSqlObject().getSql()); - //TODO Восстановление привилегий - } - } - else - { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.detailsPrintlnRed(e.getLocalizedMessage()); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - st.close(); - } - return true; - } - - @Override - public void removeMetaObject(IMetaObject obj) throws Exception - { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - - try { - if(! (obj instanceof MetaProcedure)) throw new ExceptionDBGit("Wrong IMetaObject type, expected: prc, was: " + obj.getType().getValue()); - MetaProcedure prcMeta = (MetaProcedure) obj; - DBProcedure prc = (DBProcedure) prcMeta.getSqlObject(); - if (prc == null) return; - - String schema = getPhisicalSchema(prc.getSchema()); - st.execute("DROP PROCEDURE "+schema+"."+DBAdapterPostgres.escapeNameIfNeeded(prc.getName())); - } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); - } finally { - st.close(); - } - - } - -} +package ru.fusionsoft.dbgit.postgres; + +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.DBProcedure; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaProcedure; +import ru.fusionsoft.dbgit.meta.NameMeta; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; +import ru.fusionsoft.dbgit.utils.StringProperties; + +import java.sql.Connection; +import java.text.MessageFormat; +import java.util.Map; + +public class DBRestoreProcedurePostgres extends DBRestoreAdapter { + + @Override + public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + try { + if (obj instanceof MetaProcedure) { + MetaProcedure restoreProc = (MetaProcedure)obj; + NameMeta nm = new NameMeta(restoreProc); + String restoreProcName = nm.getName(); + Map procs = adapter.getProcedures(nm.getSchema()); + boolean exist = false; + if(!(procs.isEmpty() || procs == null)) { + for(DBProcedure prc : procs.values()) { + if(restoreProcName.equals(prc.getName())){ + exist = true; + + //if codes differ + if( !restoreProc.getSqlObject().getSql() + .replaceAll("\\s+", "") + .equals(prc.getSql().replaceAll("\\s+", "")) + ) { + st.execute(restoreProc.getSqlObject().getSql()); + } + //if owners differ + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false) && !restoreProc.getSqlObject().getOwner().equals(prc.getOwner())) { + StringProperties restoreProcArgs = restoreProc.getSqlObject().getOptions().get("arguments"); + String args = restoreProcArgs != null ? restoreProcArgs.getData().replaceAll("(\\w+ \\w+) (DEFAULT [^\\,\\n]+)(\\,|\\b)", "$1") : ""; + + st.execute(MessageFormat.format("ALTER PROCEDURE {0}.{1}({2}) OWNER TO \"{3}\"" + , nm.getSchema() + , adapter.escapeNameIfNeeded(restoreProcName) + , args + , restoreProc.getSqlObject().getOwner())); + } + //TODO Восстановление привилегий + } + } + } + if(!exist){ + st.execute(restoreProc.getSqlObject().getSql()); + //TODO Восстановление привилегий + } + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "procedure", obj.getType().getValue() + )); + } + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } finally { + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + st.close(); + } + return true; + } + + @Override + public void removeMetaObject(IMetaObject obj) throws Exception + { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + + try { + if(! (obj instanceof MetaProcedure)) throw new ExceptionDBGit("Wrong IMetaObject type, expected: prc, was: " + obj.getType().getValue()); + MetaProcedure prcMeta = (MetaProcedure) obj; + DBProcedure prc = (DBProcedure) prcMeta.getSqlObject(); + if (prc == null) return; + + String schema = getPhisicalSchema(prc.getSchema()); + st.execute("DROP PROCEDURE "+schema+"."+adapter.escapeNameIfNeeded(prc.getName())); + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); + } finally { + st.close(); + } + + } + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreRolePostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreRolePostgres.java index 690c950..4f7310d 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreRolePostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreRolePostgres.java @@ -19,7 +19,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreRole").withParams(obj.getName()), 1); try { if (obj instanceof MetaRole) { MetaRole restoreRole = (MetaRole)obj; @@ -193,14 +192,15 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "role", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreSchemaPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreSchemaPostgres.java index 4e214ce..6bce6ca 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreSchemaPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreSchemaPostgres.java @@ -1,66 +1,71 @@ -package ru.fusionsoft.dbgit.postgres; -import java.sql.Connection; -import java.util.Map; - -import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.dbobjects.DBSchema; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaSchema; -import ru.fusionsoft.dbgit.statement.StatementLogging; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - - -public class DBRestoreSchemaPostgres extends DBRestoreAdapter { - @Override - public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreSchema").withParams(obj.getName()), 1); - try { - if (obj instanceof MetaSchema) { - MetaSchema restoreSchema = (MetaSchema)obj; - Map schs = adapter.getSchemes(); - boolean exist = false; - if(!(schs.isEmpty() || schs == null)) { - for(DBSchema sch:schs.values()) { - if(restoreSchema.getObjectOption().getName().equals(sch.getName())){ - exist = true; - //String test1 = changedsch.getObjectOption().getName(); - //String test2 = changedsch.getObjectOption().getOptions().getChildren().get("usename").getData(); - if(!restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData().equals(sch.getOptions().getChildren().get("usename").getData())) { - st.execute("ALTER SCHEMA "+ restoreSchema.getObjectOption().getName() +" OWNER TO "+ - restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData()); - } - //TODO Восстановление привилегий - } - } - } - if(!exist){ - st.execute("CREATE SCHEMA "+restoreSchema.getObjectOption().getName() +" AUTHORIZATION "+ - restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData()); - //TODO Восстановление привилегий - } - } - else - { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - st.close(); - } - return true; - } - - public void removeMetaObject(IMetaObject obj) { - // TODO Auto-generated method stub - } - -} +package ru.fusionsoft.dbgit.postgres; +import java.sql.Connection; +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.DBSchema; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaSchema; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + + +public class DBRestoreSchemaPostgres extends DBRestoreAdapter { + @Override + public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + try { + if (obj instanceof MetaSchema) { + MetaSchema restoreSchema = (MetaSchema)obj; + Map schs = adapter.getSchemes(); + boolean exist = false; + if(!(schs.isEmpty() || schs == null)) { + for(DBSchema sch:schs.values()) { + if(restoreSchema.getObjectOption().getName().equals(sch.getName())){ + exist = true; + //String test1 = changedsch.getObjectOption().getName(); + //String test2 = changedsch.getObjectOption().getOptions().getChildren().get("usename").getData(); + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + if(!restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData().equals(sch.getOptions().getChildren().get("usename").getData())) { + st.execute( + "ALTER SCHEMA "+ restoreSchema.getObjectOption().getName() +" OWNER TO \""+ + restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData() + "\"" + ); + } + } + //TODO Восстановление привилегий + } + } + } + if(!exist){ + st.execute("CREATE SCHEMA "+restoreSchema.getObjectOption().getName() +" AUTHORIZATION "+ + restoreSchema.getObjectOption().getOptions().getChildren().get("usename").getData()); + //TODO Восстановление привилегий + } + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "schema", obj.getType().getValue() + )); + } + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } finally { + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + st.close(); + } + return true; + } + + public void removeMetaObject(IMetaObject obj) { + // TODO Auto-generated method stub + } + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreSequencePostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreSequencePostgres.java index 7fd26c2..8c91460 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreSequencePostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreSequencePostgres.java @@ -1,137 +1,148 @@ -package ru.fusionsoft.dbgit.postgres; - -import java.sql.Connection; -import java.util.Map; - -import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.dbobjects.DBFunction; -import ru.fusionsoft.dbgit.dbobjects.DBSequence; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaFunction; -import ru.fusionsoft.dbgit.meta.MetaSequence; -import ru.fusionsoft.dbgit.statement.StatementLogging; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class DBRestoreSequencePostgres extends DBRestoreAdapter { - - @Override - public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreSeq").withParams(obj.getName()), 1); - try { - if (obj instanceof MetaSequence) { - MetaSequence restoreSeq = (MetaSequence)obj; - Map seqs = adapter.getSequences(((MetaSequence) obj).getSequence().getSchema()); - boolean exist = false; - if(!(seqs.isEmpty() || seqs == null)) { - for(DBSequence seq:seqs.values()) { - if(restoreSeq.getSequence().getName().equals(seq.getName())){ - String query=""; - exist = true; - String sequence = restoreSeq.getSequence().getSchema()+ "." +restoreSeq.getSequence().getName(); - if(!restoreSeq.getSequence().getOptions().get("cycle_option").equals(seq.getOptions().get("cycle_option"))) { - if(restoreSeq.getSequence().getOptions().get("cycle_option").equals("YES")) { - query+="alter sequence "+sequence + " cycle;\n"; - } - else { - query+="alter sequence "+sequence + " no cycle;\n"; - } - } - - if(!restoreSeq.getSequence().getOptions().get("increment").equals(seq.getOptions().get("increment"))) { - query+="alter sequence "+sequence+ " increment "+restoreSeq.getSequence().getOptions().get("increment")+";\n"; - } - - if(!restoreSeq.getSequence().getOptions().get("start_value").equals(seq.getOptions().get("start_value"))) { - query+="alter sequence "+sequence+" start "+restoreSeq.getSequence().getOptions().get("start_value")+";\n"; - } - - if(!restoreSeq.getSequence().getOptions().get("minimum_value").equals(seq.getOptions().get("minimum_value"))) { - query+="alter sequence "+sequence+ " minvalue "+restoreSeq.getSequence().getOptions().get("minimum_value")+";\n"; - } - - if(!restoreSeq.getSequence().getOptions().get("maximum_value").equals(seq.getOptions().get("maximum_value"))) { - query+="alter sequence "+sequence + " maxvalue "+restoreSeq.getSequence().getOptions().get("maximum_value")+";\n"; - } - - if(!restoreSeq.getSequence().getOptions().get("owner").equals(seq.getOptions().get("owner"))) { - query+="alter sequence "+sequence+" owner to "+restoreSeq.getSequence().getOptions().get("owner")+";\n"; - } - if(query.length()>1) { - st.execute(query); - } - //TODO Восстановление привилегий - } - } - } - if(!exist){ - String query=""; - String seqName = restoreSeq.getSequence().getName(); - String schema = restoreSeq.getSequence().getSchema(); - if(restoreSeq.getSequence().getOptions().get("cycle_option").equals("YES")){ - query+="create sequence \"" + schema + "\".\"" + seqName+"\"" + - "cycle \n"+ - "increment" + restoreSeq.getSequence().getOptions().get("increment")+"\n"+ - "start " + restoreSeq.getSequence().getOptions().get("start_value")+"\n"+ - "minvalue "+ restoreSeq.getSequence().getOptions().get("minimum_value")+"\n"+ - "maxvalue " + restoreSeq.getSequence().getOptions().get("maximum_value")+";\n"; - query+="alter sequence \""+ schema + "\".\"" + seqName+"\" owner to\""+ restoreSeq.getSequence().getOptions().get("owner")+"\";"; - } - else { - query+="create sequence \"" + schema + "\".\"" + seqName+"\"" + - "no cycle \n"+ - "increment " + restoreSeq.getSequence().getOptions().get("increment")+"\n"+ - "start " + restoreSeq.getSequence().getOptions().get("start_value")+"\n"+ - "minvalue "+ restoreSeq.getSequence().getOptions().get("minimum_value")+"\n"+ - "maxvalue " + restoreSeq.getSequence().getOptions().get("maximum_value")+";\n"; - query+="alter sequence \""+ schema + "\".\"" + seqName+"\" owner to\""+ restoreSeq.getSequence().getOptions().get("owner")+"\";"; - } - st.execute(query); - //TODO Восстановление привилегий - } - } - else - { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - st.close(); - } - return true; - } - - @Override - public void removeMetaObject(IMetaObject obj) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - - try { - if(! (obj instanceof MetaSequence)) throw new ExceptionDBGit("Wrong IMetaObject type, expected: seq, was: " + obj.getType().getValue()); - MetaSequence seqMeta = (MetaSequence) obj; - DBSequence seq = seqMeta.getSequence(); - if (seq == null) return; - - String schema = getPhisicalSchema(seq.getSchema()); - st.execute("DROP SEQUENCE IF EXISTS "+DBAdapterPostgres.escapeNameIfNeeded(schema)+"."+DBAdapterPostgres.escapeNameIfNeeded(seq.getName())); - - } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); - } finally { - st.close(); - } - - } - -} +package ru.fusionsoft.dbgit.postgres; + +import java.sql.Connection; +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.DBSequence; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaSequence; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class DBRestoreSequencePostgres extends DBRestoreAdapter { + + @Override + public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + try { + if (obj instanceof MetaSequence) { + MetaSequence restoreSeq = (MetaSequence)obj; + Map seqs = adapter.getSequences(((MetaSequence) obj).getSequence().getSchema()); + boolean exist = false; + if(!(seqs.isEmpty() || seqs == null)) { + for(DBSequence seq:seqs.values()) { + if(restoreSeq.getSequence().getName().equals(seq.getName())){ + String query=""; + exist = true; + String sequence = restoreSeq.getSequence().getSchema()+ "." +restoreSeq.getSequence().getName(); + if(!restoreSeq.getSequence().getOptions().get("cycle_option").equals(seq.getOptions().get("cycle_option"))) { + if(restoreSeq.getSequence().getOptions().get("cycle_option").equals("YES")) { + query+="alter sequence "+sequence + " cycle;\n"; + } + else { + query+="alter sequence "+sequence + " no cycle;\n"; + } + } + + if(!restoreSeq.getSequence().getOptions().get("increment").equals(seq.getOptions().get("increment"))) { + query+="alter sequence "+sequence+ " increment "+restoreSeq.getSequence().getOptions().get("increment")+";\n"; + } + + if(!restoreSeq.getSequence().getOptions().get("start_value").equals(seq.getOptions().get("start_value"))) { + query+="alter sequence "+sequence+" start "+restoreSeq.getSequence().getOptions().get("start_value")+";\n"; + } + + if(!restoreSeq.getSequence().getOptions().get("minimum_value").equals(seq.getOptions().get("minimum_value"))) { + query+="alter sequence "+sequence+ " minvalue "+restoreSeq.getSequence().getOptions().get("minimum_value")+";\n"; + } + + if(!restoreSeq.getSequence().getOptions().get("maximum_value").equals(seq.getOptions().get("maximum_value"))) { + query+="alter sequence "+sequence + " maxvalue "+restoreSeq.getSequence().getOptions().get("maximum_value")+";\n"; + } + + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + + if(!restoreSeq.getSequence().getOptions().get("owner").equals(seq.getOptions().get("owner"))) { + if(seq.getOptions().get("blocking_table") != null){ + String tableName = adapter.escapeNameIfNeeded(seq.getOptions().get("blocking_table").getData()); + query+="alter table "+tableName+ " owner to \""+restoreSeq.getSequence().getOptions().get("owner")+"\";\n"; + } + query+="alter sequence "+sequence+" owner to \""+restoreSeq.getSequence().getOptions().get("owner")+"\";\n"; + } + } + + if(query.length()>1) { + st.execute(query); + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + //TODO Восстановление привилегий + } + } + } + if(!exist){ + String query=""; + String seqName = restoreSeq.getSequence().getName(); + String schema = restoreSeq.getSequence().getSchema(); + if(restoreSeq.getSequence().getOptions().get("cycle_option").equals("YES")){ + query+="create sequence \"" + schema + "\".\"" + seqName+"\"" + + "cycle \n"+ + "increment" + restoreSeq.getSequence().getOptions().get("increment")+"\n"+ + "start " + restoreSeq.getSequence().getOptions().get("start_value")+"\n"+ + "minvalue "+ restoreSeq.getSequence().getOptions().get("minimum_value")+"\n"+ + "maxvalue " + restoreSeq.getSequence().getOptions().get("maximum_value")+";\n"; + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + query+="alter sequence \""+ schema + "\".\"" + seqName+"\" owner to\""+ restoreSeq.getSequence().getOptions().get("owner")+"\";"; + } + } + else { + query+="create sequence \"" + schema + "\".\"" + seqName+"\"" + + " no cycle \n"+ + "increment " + restoreSeq.getSequence().getOptions().get("increment")+"\n"+ + "start " + restoreSeq.getSequence().getOptions().get("start_value")+"\n"+ + "minvalue "+ restoreSeq.getSequence().getOptions().get("minimum_value")+"\n"+ + "maxvalue " + restoreSeq.getSequence().getOptions().get("maximum_value")+";\n"; + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + query+="alter sequence \""+ schema + "\".\"" + seqName+"\" owner to \""+ restoreSeq.getSequence().getOptions().get("owner")+"\";"; + } + } + st.execute(query); + //TODO Восстановление привилегий + } + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "sequence", obj.getType().getValue() + )); + } + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } finally { + + st.close(); + } + return true; + } + + @Override + public void removeMetaObject(IMetaObject obj) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + + try { + if(! (obj instanceof MetaSequence)) throw new ExceptionDBGit("Wrong IMetaObject type, expected: seq, was: " + obj.getType().getValue()); + MetaSequence seqMeta = (MetaSequence) obj; + DBSequence seq = seqMeta.getSequence(); + if (seq == null) return; + + String schema = getPhisicalSchema(seq.getSchema()); + st.execute("DROP SEQUENCE IF EXISTS "+adapter.escapeNameIfNeeded(schema)+"."+adapter.escapeNameIfNeeded(seq.getName())); + + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); + } finally { + st.close(); + } + + } + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableDataPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableDataPostgres.java index 39562f2..4b5da5c 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableDataPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableDataPostgres.java @@ -1,633 +1,591 @@ -package ru.fusionsoft.dbgit.postgres; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.sql.Clob; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.stream.Collectors; - -import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.core.GitMetaDataManager; -import ru.fusionsoft.dbgit.core.SchemaSynonym; -import ru.fusionsoft.dbgit.data_table.BooleanData; -import ru.fusionsoft.dbgit.data_table.DateData; -import ru.fusionsoft.dbgit.data_table.ICellData; -import ru.fusionsoft.dbgit.data_table.LongData; -import ru.fusionsoft.dbgit.data_table.MapFileData; -import ru.fusionsoft.dbgit.data_table.RowData; -import ru.fusionsoft.dbgit.data_table.StringData; -import ru.fusionsoft.dbgit.data_table.TextFileData; -import ru.fusionsoft.dbgit.data_table.TreeMapRowData; -import ru.fusionsoft.dbgit.dbobjects.DBConstraint; -import ru.fusionsoft.dbgit.dbobjects.DBTableField; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaTable; -import ru.fusionsoft.dbgit.meta.MetaTableData; -import ru.fusionsoft.dbgit.statement.PrepareStatementLogging; -import ru.fusionsoft.dbgit.statement.StatementLogging; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -import com.google.common.collect.MapDifference; -import com.google.common.collect.MapDifference.ValueDifference; -import com.google.common.collect.Maps; - -public class DBRestoreTableDataPostgres extends DBRestoreAdapter { - - @Override - public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { - if (obj instanceof MetaTableData) { - MetaTableData currentTableData; - MetaTableData restoreTableData = (MetaTableData)obj; - GitMetaDataManager gitMetaMng = GitMetaDataManager.getInstance(); - //TODO не факт что в кеше есть мета описание нашей таблицы, точнее ее не будет если при старте ресторе таблицы в бд не было совсем - - IMetaObject currentMetaObj = gitMetaMng.getCacheDBMetaObject(obj.getName()); - - if (currentMetaObj instanceof MetaTableData || currentMetaObj == null) { - - if(Integer.valueOf(step).equals(0)) { - removeTableConstraintsPostgres(restoreTableData.getMetaTable()); - return false; - } - if(Integer.valueOf(step).equals(1)) { - String schema = getPhisicalSchema(restoreTableData.getTable().getSchema()); - schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); - - if (currentMetaObj != null) { - currentTableData = (MetaTableData) currentMetaObj; - } else { - currentTableData = new MetaTableData(); - currentTableData.setTable(restoreTableData.getTable()); - currentTableData.getTable().setSchema(schema); - - currentTableData.setMapRows(new TreeMapRowData()); - currentTableData.setDataTable(restoreTableData.getDataTable()); - } - currentTableData.getmapRows().clear(); - - if (getAdapter().getTable(schema, currentTableData.getTable().getName()) != null) { - currentTableData.setDataTable(getAdapter().getTableData(schema, currentTableData.getTable().getName())); - - ResultSet rs = currentTableData.getDataTable().getResultSet(); - - TreeMapRowData mapRows = new TreeMapRowData(); - - MetaTable metaTable = new MetaTable(currentTableData.getTable()); - metaTable.loadFromDB(currentTableData.getTable()); - - if (rs != null) { - while(rs.next()) { - RowData rd = new RowData(rs, metaTable); - mapRows.put(rd.calcRowKey(metaTable.getIdColumns()), rd); - } - } - currentTableData.setMapRows(mapRows); - } - /* - ConsoleWriter.println("curr:"); - currentTableData.getmapRows().keySet().forEach(key -> ConsoleWriter.println("hash: " + key)); - ConsoleWriter.println("rest:"); - restoreTableData.getmapRows().keySet().forEach(key -> ConsoleWriter.println("hash: " + key)); - */ - restoreTableDataPostgres(restoreTableData,currentTableData); - return false; - } - if(Integer.valueOf(step).equals(-2)) { - restoreTableConstraintPostgres(restoreTableData.getMetaTable()); - return false; - } - return true; - } - else - { - //TODO WTF???? - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - //return true; - } - } - else - { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } - - public void restoreTableDataPostgres(MetaTableData restoreTableData, MetaTableData currentTableData) throws Exception{ - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - try { - if (restoreTableData.getmapRows() == null) - restoreTableData.setMapRows(new TreeMapRowData()); - - String fields = ""; - if (restoreTableData.getmapRows().size() > 0) { - //fields = keysToString(restoreTableData.getmapRows().firstEntry().getValue().getData().keySet().stream().map(DBAdapterPostgres::escapeNameIfNeeded).collect(Collectors.toSet())) + " values "; - - Comparator comparator = Comparator.comparing(DBTableField::getOrder); - fields = "(" + restoreTableData.getMetaTableFromFile().getFields().entrySet().stream() - .sorted(Comparator.comparing(e -> e.getValue().getOrder())) - .map(entry -> DBAdapterPostgres.escapeNameIfNeeded(entry.getValue().getName())) - .collect(Collectors.joining(", ")) - + ") values "; - - } - - MapDifference diffTableData = Maps.difference(restoreTableData.getmapRows(),currentTableData.getmapRows()); - String schema = getPhisicalSchema(restoreTableData.getTable().getSchema()); - - schema = (SchemaSynonym.getInstance().getSchema(schema) == null) ? schema : SchemaSynonym.getInstance().getSchema(schema); - String tblNameUnescaped = schema + "." + restoreTableData.getTable().getName(); - String tblNameEscaped = DBAdapterPostgres.escapeNameIfNeeded(schema) + "." + DBAdapterPostgres.escapeNameIfNeeded(restoreTableData.getTable().getName()); - - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "tableData").withParams(tblNameUnescaped) + "\n", 1); - - ResultSet rsTypes = st.executeQuery("select column_name, data_type from information_schema.columns \r\n" + - "where lower(table_schema||'.'||table_name) = lower('" + tblNameUnescaped + "')"); - - HashMap colTypes = new HashMap(); - while (rsTypes.next()) { - colTypes.put(rsTypes.getString("column_name"), rsTypes.getString("data_type")); - } - - - if(!diffTableData.entriesOnlyOnLeft().isEmpty()) { - - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "inserting"), 2); - - for(RowData rowData:diffTableData.entriesOnlyOnLeft().values()) { - ArrayList fieldsList = new ArrayList(rowData.getData().keySet().stream().map(DBAdapterPostgres::escapeNameIfNeeded).collect(Collectors.toList())); - - String insertQuery = "insert into " + tblNameEscaped + - fields+valuesToString(rowData.getData().values(), colTypes, fieldsList) + ";\n"; - - ConsoleWriter.detailsPrintLn(insertQuery); - - PrepareStatementLogging ps = new PrepareStatementLogging(connect, insertQuery, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - int i = 0; - - for (ICellData data : rowData.getData().values()) { - i++; - ConsoleWriter.detailsPrintLn(data.getSQLData()); - - ResultSet rs = st.executeQuery("select data_type from information_schema.columns \r\n" + - "where lower(table_schema||'.'||table_name) = lower('" + tblNameUnescaped + "') and lower(column_name) = '" + fieldsList.get(i - 1) + "'"); - - boolean isBoolean = false; - while (rs.next()) { - if (rs.getString("data_type").contains("boolean")) { - isBoolean = true; - } - } - - //ps = setValues(data, i, ps, isBoolean); - } - - //if (adapter.isExecSql()) - // ps.execute(); - //ps.close(); - - st.execute(insertQuery); - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - - if(!diffTableData.entriesOnlyOnRight().isEmpty()){ - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "deleting"), 2); - String deleteQuery=""; - Map primarykeys = new HashMap(); - for(RowData rowData:diffTableData.entriesOnlyOnRight().values()) { - Map tempcols = rowData.getData(); - String[] keysArray = rowData.getKey().split("_"); - for(String key:keysArray) { - for (String o : tempcols.keySet()) { - if (tempcols.get(o) == null || tempcols.get(o).convertToString() == null) continue; - if (tempcols.get(o).convertToString().equals(key)) { - primarykeys.put(o, tempcols.get(o).convertToString()); - tempcols.remove(o); - break; - } - } - } - String delFields="("; - String delValues="("; - StringJoiner fieldJoiner = new StringJoiner(","); - StringJoiner valuejoiner = new StringJoiner(","); - for (Map.Entry entry : primarykeys.entrySet()) { - fieldJoiner.add("\""+entry.getKey()+"\""); - valuejoiner.add("\'"+entry.getValue()+"\'"); - } - delFields+=fieldJoiner.toString()+")"; - delValues+=valuejoiner.toString()+")"; - primarykeys.clear(); - if (delValues.length() > 3) - deleteQuery+="delete from " + tblNameUnescaped+ - " where " + delFields + " = " + delValues + ";\n"; - if(deleteQuery.length() > 50000 ){ - st.execute(deleteQuery); - deleteQuery = ""; - } - } - if(deleteQuery.length()>1) { - st.execute(deleteQuery); - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - - if(!diffTableData.entriesDiffering().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "updating"), 2); - String updateQuery=""; - Map primarykeys = new HashMap(); - for(ValueDifference diffRowData:diffTableData.entriesDiffering().values()) { - if(!diffRowData.leftValue().getHashRow().equals(diffRowData.rightValue().getHashRow())) { - Map tempCols = diffRowData.leftValue().getData(); - String[] keysArray = diffRowData.leftValue().getKey().split("_"); - for(String key:keysArray) { - for (String o : tempCols.keySet()) { - if (tempCols.get(o) == null || tempCols.get(o).convertToString() == null) continue; - if (tempCols.get(o).convertToString().equals(key)) { - primarykeys.put(o, tempCols.get(o).convertToString()); - tempCols.remove(o); - break; - } - } - } - if(!tempCols.isEmpty()) { - String keyFields="("; - String keyValues="("; - StringJoiner fieldJoiner = new StringJoiner(","); - StringJoiner valuejoiner = new StringJoiner(","); - for (Map.Entry entry : primarykeys.entrySet()) { - fieldJoiner.add("\""+entry.getKey()+"\""); - valuejoiner.add("\'"+entry.getValue()+"\'"); - } - keyFields+=fieldJoiner.toString()+")"; - keyValues+=valuejoiner.toString()+")"; - primarykeys.clear(); - - StringJoiner updfieldJoiner = new StringJoiner(","); - StringJoiner updvaluejoiner = new StringJoiner(","); - String updFields="("; - String updValues="("; - - for (Map.Entry entry : tempCols.entrySet()) { - updfieldJoiner.add("\""+entry.getKey()+"\""); - //updvaluejoiner.add("\'"+entry.getValue().convertToString()+"\'"); - //updvaluejoiner.add("?"); - } - - ArrayList fieldsList = new ArrayList(diffRowData.leftValue().getData().keySet()); - - updFields+=updfieldJoiner.toString()+")"; - updValues+=updvaluejoiner.toString()+")"; - - updateQuery="update "+tblNameEscaped+ - " set "+updFields + " = " + valuesToString(tempCols.values(), colTypes, fieldsList) + " where " + keyFields+ "=" +keyValues+";\n"; - - ConsoleWriter.detailsPrintLn(updateQuery); - - PrepareStatementLogging ps = new PrepareStatementLogging(connect, updateQuery, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - int i = 0; - - ConsoleWriter.detailsPrintLn("vals for " + keyValues + ":" + diffRowData.leftValue().getData().values()); - for (ICellData data : diffRowData.leftValue().getData().values()) { - i++; - ConsoleWriter.detailsPrintLn(data.getSQLData()); - - ResultSet rs = st.executeQuery("select data_type from information_schema.columns \r\n" + - "where lower(table_schema||'.'||table_name) = lower('" + tblNameUnescaped + "') and lower(column_name) = '" + fieldsList.get(i - 1) + "'"); - - boolean isBoolean = false; - while (rs.next()) { - if (rs.getString("data_type").toLowerCase().contains("boolean")) { - isBoolean = true; - } - } - //ps = setValues(data, i, ps, isBoolean); - } - /* - if (adapter.isExecSql()) - ps.execute(); - ps.close(); - updateQuery = ""; - */ - - - - //if(updateQuery.length() > 50000 ){ - st.execute(updateQuery); - updateQuery = ""; - //} - - } - - } - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - if(updateQuery.length()>1) { - ConsoleWriter.println(updateQuery); - st.execute(updateQuery); - } - } - - } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(restoreTableData.getTable().getSchema() + "." + restoreTableData.getTable().getName()), e); - } finally { - st.close(); - } - } - - public String valuesToString(Collection datas, HashMap colTypes, ArrayList fieldsList) throws ExceptionDBGit, IOException { - String values="("; - StringJoiner joiner = new StringJoiner(","); - int i = 0; - for (ICellData data : datas) { - boolean isBoolean = ((colTypes.get(fieldsList.get(i)) != null) && (colTypes.get(fieldsList.get(i)).toLowerCase().contains("boolean"))); - - if (data instanceof TextFileData) { - if (((TextFileData) data).getFile() == null || ((TextFileData) data).getFile().getName().contains("null")) { - joiner.add("null"); - } else { - FileInputStream fis = new FileInputStream(((MapFileData) data).getFile()); - BufferedReader br = new BufferedReader(new InputStreamReader(fis)); - - StringBuilder sb = new StringBuilder(); - String line; - while(( line = br.readLine()) != null ) { - sb.append( line ); - sb.append( '\n' ); - } - br.close(); - - fis.close(); - String res = "'" + sb.toString().replace("'", "''") - .replace("\\", "\\\\") - .replace("\n", "' || chr(10) || '") - .replace("\0", "' || '\\000' || '") - + "'"; - - if (res.endsWith(" || chr(10) || ''")) { - res = res.substring(0, res.length() - " || chr(10) || ''".length()); - } - joiner.add(res); - - - } - } else if (data instanceof MapFileData) { - if (((MapFileData) data).getFile() == null || ((MapFileData) data).getFile().getName().contains("null")) { - joiner.add("null"); - } else { - - FileInputStream fis = new FileInputStream(((MapFileData) data).getFile()); - - int byteRead; - StringBuilder sb = new StringBuilder(); - - while ((byteRead = fis.read()) != -1) { - String hex = Integer.toHexString(byteRead); - if (hex.length() == 1) hex = "0" + hex; - - sb.append(hex); - } - fis.close(); - joiner.add("decode('" + sb.toString() + "', 'hex')"); - - /* - joiner1.add("decode('" + sb.toString().replace("'", "''") - .replace("\\", "\\\\") - .replace("\n", "' || chr(10) || '") - .replace("\0", "' || '\\000' || '") - + "', 'escape')");*/ - } - } else if (data instanceof DateData) { - Date date = ((DateData) data).getDate(); - SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); - if (date != null) - joiner.add("TO_TIMESTAMP('" + format.format(date) + "', 'YYYYMMDDHH24MISS')"); - else - joiner.add("null"); - } else if (data instanceof BooleanData) { - if (((BooleanData) data).getValue() != null) - joiner.add(((BooleanData) data).getValue().toString()); - else - joiner.add("null"); - } else if (data instanceof LongData) { - String dt = data.getSQLData().replace("'", ""); - - if (isBoolean) { - if (dt == null || dt.equals("")) - joiner.add("null"); - else if (dt.equals("1")) - joiner.add("true"); - else - joiner.add("false"); - } else { - if (!dt.equals("")) - joiner.add(dt); - else - joiner.add("null"); - } - } else { - String dt = ((StringData) data).getValue(); - if (isBoolean) { - if (dt == null || dt.equals("")) - joiner.add("null"); - else if (dt.startsWith("t") || dt.startsWith("T") || dt.equals("1") || dt.startsWith("y") || dt.startsWith("Y")) - joiner.add("true"); - else - joiner.add("false"); - } else { - if (dt != null) - joiner.add("'" + dt.replace("'", "''") + "'"); - else - joiner.add("null"); - } - //joiner.add(data.getSQLData()); - - } - - //joiner.add("?"); - i++; - } - //ConsoleWriter.println("joiner: " + joiner1); - values+=joiner.toString()+")"; - return values; - } - - public String keysToString(Set keys) { - String fields=""; - if(keys.size()>1) { - String[] fieldsArray = keys.toArray(new String[keys.size()]); - fields="("+(fieldsArray[0].equals(fieldsArray[0].toLowerCase()) ? fieldsArray[0] : "\"" + fieldsArray[0] + "\""); - for(int i=1;igetDataTable() too after ^ "else" clause + currentTableData.getmapRows().clear(); + + 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(); + + TreeMapRowData mapRows = new TreeMapRowData(); + + MetaTable metaTable = new MetaTable(currentTableData.getTable()); + //ALSO loads data from database if fields vary + metaTable.loadFromDB(currentTableData.getTable()); + + if (rs != null) { + while(rs.next()) { + RowData rd = new RowData(rs, metaTable); + mapRows.put(rd.calcRowKey(metaTable.getIdColumns()), rd); + } + } + currentTableData.setMapRows(mapRows); + } + /* + ConsoleWriter.println("curr:"); + currentTableData.getmapRows().keySet().forEach(key -> ConsoleWriter.println("hash: " + key)); + ConsoleWriter.println("rest:"); + restoreTableData.getmapRows().keySet().forEach(key -> ConsoleWriter.println("hash: " + key)); + */ + restoreTableDataPostgres(restoreTableData,currentTableData); + return false; + } + if(Integer.valueOf(step).equals(-2)) { + restoreTableConstraintPostgres(restoreTableData.getMetaTable()); + return false; + } + return true; + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table data cached", obj.getType().getValue() + )); + } + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table data", obj.getType().getValue() + )); + } + } + + public void restoreTableDataPostgres(MetaTableData restoreTableData, MetaTableData currentTableData) throws Exception{ + //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) { + final CharSequence msg = DBGitLang.getInstance().getValue("errors", "restore", "emptyRowsList").toString(); + throw new ExceptionDBGit(msg); + } + + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + + MapDifference diffTableData = Maps.difference(restoreTableData.getmapRows(), currentTableData.getmapRows()); + try (StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql())) { + + String schema = getPhisicalSchema(restoreTableData.getTable().getSchema()); + String tblNameEscaped = adapter.escapeNameIfNeeded(schema) + "." + adapter.escapeNameIfNeeded(restoreTableData.getTable().getName()); + String fields = getFieldsPrefix(restoreTableData); + Map colTypes = getColumnDataTypes(restoreTableData.getMetaTable(), st); + Set keyNames = restoreTableData.getMetaTable().getFields().values().stream() + .filter(DBTableField::getIsPrimaryKey) + .map(DBTableField::getName) + .collect(Collectors.toSet()); + + //DELETE + if (!diffTableData.entriesOnlyOnRight().isEmpty()) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "deleting"), messageLevel); + StringBuilder deleteQuery = new StringBuilder(); + + for (RowData rowData : diffTableData.entriesOnlyOnRight().values()) { + StringJoiner fieldJoiner = new StringJoiner(","); + StringJoiner valuejoiner = new StringJoiner(","); + + for( Map.Entry entry : rowData.getData(currentTableData.getFields()).entrySet()) { + if (keyNames.contains(entry.getKey())) { + fieldJoiner.add("\"" + entry.getKey() + "\""); + final String value = entry.getValue().convertToString(); + if( value.matches("-?\\d+(\\.0)?") ) { + valuejoiner.add( String.valueOf( (long) Double.parseDouble(value) ) ); + } else { + valuejoiner.add("'" + value + "'"); + } + } + } + + String delFields = "(" + fieldJoiner.toString() + ")"; + String delValues = "(" + valuejoiner.toString() + ")"; + + if (delValues.length() > 2){ + final String ddl = MessageFormat.format( + "DELETE FROM {0} WHERE {1} = {2};", + tblNameEscaped, delFields, delValues + ); + deleteQuery.append(ddl).append("\n"); + ConsoleWriter.detailsPrintln(ddl, messageLevel + 1); + } + if (deleteQuery.length() > 50000) { + st.execute(deleteQuery.toString()); + deleteQuery = new StringBuilder(); + } + } + if (deleteQuery.length() > 1) { + st.execute(deleteQuery.toString()); + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + + //UPDATE + if (!diffTableData.entriesDiffering().isEmpty()) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "updating"), messageLevel); + String updateQuery = ""; + Map primarykeys = new HashMap(); + + for (ValueDifference diffRowData : diffTableData.entriesDiffering().values()) { + if (!diffRowData.leftValue().getHashRow().equals(diffRowData.rightValue().getHashRow())) { + + 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)) { + primarykeys.put(key, tempCols.get(key).convertToString()); + tempCols.remove(key); + } + } + + + if (!tempCols.isEmpty()) { + StringJoiner keyFieldsJoiner = new StringJoiner(","); + StringJoiner keyValuesJoiner = new StringJoiner(","); + for (Map.Entry entry : primarykeys.entrySet()) { + keyFieldsJoiner.add("\"" + entry.getKey() + "\""); + keyValuesJoiner.add("\'" + entry.getValue() + "\'"); + } + primarykeys.clear(); + + + StringJoiner updFieldJoiner = new StringJoiner(","); + tempCols.forEach( (key, value) -> { + updFieldJoiner.add("\"" + key + "\""); + }); + + + updateQuery = "UPDATE " + tblNameEscaped + " SET (" + updFieldJoiner.toString() + ") = " + + valuesToString(tempCols.values(), colTypes, restoreTableData.getFields()) + " " + + "WHERE (" + keyFieldsJoiner.toString() + ") = (" + keyValuesJoiner.toString() + ");\n"; + + + ConsoleWriter.detailsPrintln(updateQuery, messageLevel); + st.execute(updateQuery); + updateQuery = ""; + } + + } + } + + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + if (updateQuery.length() > 1) { + ConsoleWriter.println(updateQuery, messageLevel); + st.execute(updateQuery); + } + } + + //INSERT + if (!diffTableData.entriesOnlyOnLeft().isEmpty()) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "inserting"), messageLevel); + for (RowData rowData : diffTableData.entriesOnlyOnLeft().values()) { + + String insertQuery = MessageFormat.format("INSERT INTO {0}{1}{2};" + , tblNameEscaped, fields + , valuesToString(rowData.getData(restoreTableData.getFields()).values(), colTypes, restoreTableData.getFields()) + ); + + ConsoleWriter.detailsPrintln(insertQuery, messageLevel+1); + st.execute(insertQuery); + } + ConsoleWriter.detailsPrintln(lang.getValue("general", "ok"), messageLevel); + } + + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(restoreTableData.getTable().getSchema() + "." + restoreTableData.getTable().getName()) + , e + ); + } + } + + public String valuesToString(Collection datas, Map colTypes, List fieldsList) throws ExceptionDBGit, IOException { + String values="("; + StringJoiner joiner = new StringJoiner(","); + int i = 0; + for (ICellData data : datas) { + boolean isBoolean = ((colTypes.get(fieldsList.get(i)) != null) && (colTypes.get(fieldsList.get(i)).toLowerCase().contains("boolean"))); + + if (data instanceof TextFileData) { + if (((TextFileData) data).getFile() == null || ((TextFileData) data).getFile().getName().contains("null")) { + //TODO generalize this behaviour based on some parameter + //TODO nulls if nullable, '' if not + joiner.add("''"); + } else { + FileInputStream fis = new FileInputStream(((MapFileData) data).getFile()); + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + + StringBuilder sb = new StringBuilder(); + String line; + while(( line = br.readLine()) != null ) { + sb.append( line ); + sb.append( '\n' ); + } + br.close(); + + fis.close(); + String res = "'" + sb.toString().replace("'", "''") + .replace("\\", "\\\\") +// .replace("\n", "' || chr(10) || '") + .replace("\0", "' || '\\000' || '") + + "'"; + + if (res.endsWith(" || chr(10) || ''")) { + res = res.substring(0, res.length() - " || chr(10) || ''".length()); + } + joiner.add(res); + + + } + } else if (data instanceof MapFileData) { + if (((MapFileData) data).getFile() == null || ((MapFileData) data).getFile().getName().contains("null")) { + joiner.add("null"); + } else { + + FileInputStream fis = new FileInputStream(((MapFileData) data).getFile()); + + int byteRead; + StringBuilder sb = new StringBuilder(); + + while ((byteRead = fis.read()) != -1) { + String hex = Integer.toHexString(byteRead); + if (hex.length() == 1) hex = "0" + hex; + + sb.append(hex); + } + fis.close(); + joiner.add("decode('" + sb.toString() + "', 'hex')"); + + /* + joiner1.add("decode('" + sb.toString().replace("'", "''") + .replace("\\", "\\\\") + .replace("\n", "' || chr(10) || '") + .replace("\0", "' || '\\000' || '") + + "', 'escape')");*/ + } + } else if (data instanceof DateData) { + Date date = ((DateData) data).getDate(); + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); + if (date != null) + joiner.add("TO_TIMESTAMP('" + format.format(date) + "', 'YYYYMMDDHH24MISS')"); + else + joiner.add("null"); + } else if (data instanceof BooleanData) { + if (((BooleanData) data).getValue() != null) + joiner.add(((BooleanData) data).getValue().toString()); + else + joiner.add("null"); + } else if (data instanceof LongData) { + String dt = data.getSQLData().replace("'", ""); + + if (isBoolean) { + if (dt == null || dt.equals("")) + joiner.add("null"); + else if (dt.equals("1")) + joiner.add("true"); + else + joiner.add("false"); + } else { + if (!dt.equals("")) + joiner.add(dt); + else + joiner.add("null"); + } + } else { + String dt = ((StringData) data).getValue(); + if (isBoolean) { + if (dt == null || dt.equals("")) + joiner.add("null"); + else if (dt.startsWith("t") || dt.startsWith("T") || dt.equals("1") || dt.startsWith("y") || dt.startsWith("Y")) + joiner.add("true"); + else + joiner.add("false"); + } else { + if (dt != null) + joiner.add("'" + dt.replace("'", "''") + "'"); + else + joiner.add("null"); + } + //joiner.add(data.getSQLData()); + + } + + //joiner.add("?"); + i++; + } + //ConsoleWriter.println("joiner: " + joiner1); + values+=joiner.toString()+")"; + return values; + } + + public String keysToString(Set keys) { + String fields=""; + if(keys.size()>1) { + String[] fieldsArray = keys.toArray(new String[keys.size()]); + fields="("+(fieldsArray[0].equals(fieldsArray[0].toLowerCase()) ? fieldsArray[0] : "\"" + fieldsArray[0] + "\""); + for(int i=1;i e.getValue().getOrder())) + .map(entry -> adapter.escapeNameIfNeeded(entry.getValue().getName())) + .collect(Collectors.joining(", ")) + ); + } + + private Map getColumnDataTypes(MetaTable tbl, StatementLogging st) throws SQLException { + HashMap colTypes = new HashMap(); + NameMeta nm = new NameMeta(tbl); + nm.setSchema(nm.getSchema()); + + ResultSet rsTypes = st.executeQuery(MessageFormat.format( + " select column_name, data_type from information_schema.columns \r\n" + + " where lower(table_schema) = lower(''{0}'') AND lower(table_name) = lower(''{1}'')" + , nm.getSchema(), nm.getName() + )); + + while (rsTypes.next()) { + colTypes.put(rsTypes.getString("column_name"), rsTypes.getString("data_type")); + } + return colTypes; + } + + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTablePostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTablePostgres.java index 09f5d22..a7ff235 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTablePostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTablePostgres.java @@ -7,11 +7,16 @@ import com.google.common.collect.Sets; 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.core.GitMetaDataManager; import ru.fusionsoft.dbgit.core.db.FieldType; import ru.fusionsoft.dbgit.dbobjects.*; +import ru.fusionsoft.dbgit.meta.DBGitMetaType; import ru.fusionsoft.dbgit.meta.IMetaObject; import ru.fusionsoft.dbgit.meta.MetaTable; +import ru.fusionsoft.dbgit.meta.NameMeta; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; import ru.fusionsoft.dbgit.utils.StringProperties; @@ -28,6 +33,7 @@ public class DBRestoreTablePostgres extends DBRestoreAdapter { @Override public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + if(Integer.valueOf(step).equals(0)) { restoreTablePostgres(obj); return false; @@ -43,276 +49,78 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { return false; } + if(Integer.valueOf(step).equals(-2)) { + removeTableConstraintsPostgres(obj); + removeTableIndexesPostgres(obj); + return false; + } + return true; } - - public void restoreTablePostgres(IMetaObject obj) throws Exception - { + public void removeMetaObject(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - try { - if (obj instanceof MetaTable) { - MetaTable restoreTable = (MetaTable)obj; - MetaTable existingTable = new MetaTable(restoreTable.getTable()); - - String schema = DBAdapterPostgres.escapeNameIfNeeded(getPhisicalSchema(restoreTable.getTable().getSchema().toLowerCase())); - String tblName = DBAdapterPostgres.escapeNameIfNeeded(restoreTable.getTable().getName()); - - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTable").withParams(schema+"."+tblName), 1); - - //find existing table and set tablespace or create - if(existingTable.loadFromDB()){ - StringProperties exTablespace = existingTable.getTable().getOptions().get("tablespace"); - StringProperties restoreTablespace = restoreTable.getTable().getOptions().get("tablespace"); - if( - restoreTablespace != null && ( exTablespace == null || !exTablespace.getData().equals(restoreTablespace.getData()) ) - ){ - //TODO For now in postgres context tablespace is always missing! - String restoreTablespaceSam = MessageFormat.format( - "alter table {0}.{1} set tablespace {2}" - ,schema - ,tblName - ,restoreTable.getTable().getOptions().getChildren().containsKey("tablespace") - ? restoreTable.getTable().getOptions().get("tablespace").getData() - : "pg_default" - ); - st.execute(restoreTablespaceSam); - } - - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } else { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "createTable"), 2); - String createTableDdl = MessageFormat.format( - "create table {0}.{1}() tablespace {2};\n alter table {0}.{1} owner to {3}" - ,schema - ,tblName - ,restoreTable.getTable().getOptions().getChildren().containsKey("tablespace") - ? restoreTable.getTable().getOptions().get("tablespace").getData() - : "pg_default" - ,restoreTable.getTable().getOptions().getChildren().containsKey("owner") - ? restoreTable.getTable().getOptions().get("owner").getData() - : "postgres" - ); - st.execute(createTableDdl); - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - - //restore comment - if (restoreTable.getTable().getComment() != null && restoreTable.getTable().getComment().length() > 0){ - st.execute(MessageFormat.format( - "COMMENT ON TABLE {0}.{1} IS '{2}'" - ,schema - ,tblName - ,restoreTable.getTable().getComment() - )); - } - - //restore tabl fields -// Map currentFileds = adapter.getTableFields(schema.toLowerCase(), restoreTable.getTable().getName().toLowerCase()); - MapDifference diffTableFields = Maps.difference(restoreTable.getFields(),existingTable.getFields()); - String tblSam = DBAdapterPostgres.escapeNameIfNeeded(schema) + "." + DBAdapterPostgres.escapeNameIfNeeded(tblName); - - if(!diffTableFields.entriesOnlyOnLeft().isEmpty()){ - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "addColumns"), 2); - - Comparator comparator = Comparator.comparing(DBTableField::getOrder); - - List values = new ArrayList<>(diffTableFields.entriesOnlyOnLeft().values()); - values.sort(comparator); - - for(DBTableField tblField : values) { - String fieldName = DBAdapterPostgres.escapeNameIfNeeded(tblField.getName()); - st.execute( - "alter table "+ tblSam +" add column " - + fieldName + " " - + tblField.getTypeSQL().replace("NOT NULL", "") - ); - - if (tblField.getDescription() != null && tblField.getDescription().length() > 0) - st.execute( - "COMMENT ON COLUMN " + tblSam + "." - + fieldName - + " IS '" + tblField.getDescription() + "'" - ); - - if (!tblField.getIsNullable()) { - st.execute( - "alter table " + tblSam - + " alter column " + fieldName - + " set not null" - ); - } - - if (tblField.getDefaultValue() != null && tblField.getDefaultValue().length() > 0) { - st.execute("alter table " + tblSam + " alter column " + fieldName - + " SET DEFAULT " + tblField.getDefaultValue()); - } - - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - - if(!diffTableFields.entriesOnlyOnRight().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "droppingColumns"), 2); - for(DBTableField tblField:diffTableFields.entriesOnlyOnRight().values()) { - st.execute("alter table "+ tblSam +" drop column "+ DBAdapterPostgres.escapeNameIfNeeded(tblField.getName())); - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } - - if(!diffTableFields.entriesDiffering().isEmpty()) { - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "modifyColumns"), 2); - for(ValueDifference tblField:diffTableFields.entriesDiffering().values()) { - if(!tblField.leftValue().getName().equals(tblField.rightValue().getName())) { - st.execute( - "alter table " - + tblSam - +" rename column "+ DBAdapterPostgres.escapeNameIfNeeded(tblField.rightValue().getName()) - +" to "+ DBAdapterPostgres.escapeNameIfNeeded(tblField.leftValue().getName()) - ); - } - - if (restoreTable.getTable().getComment() != null && restoreTable.getTable().getComment().length() > 0) - st.execute("COMMENT ON COLUMN " + tblSam + "." + DBAdapterPostgres.escapeNameIfNeeded(tblField.leftValue().getName()) + " IS '" + tblField.leftValue().getDescription() + "'"); - - if( !tblField.leftValue().getTypeSQL().equals(tblField.rightValue().getTypeSQL()) - && tblField.rightValue().getTypeUniversal() != FieldType.BOOLEAN) { - st.execute( - "alter table " - + tblSam - +" alter column "+ DBAdapterPostgres.escapeNameIfNeeded(tblField.leftValue().getName()) - +" type "+ tblField.leftValue().getTypeSQL().replace("NOT NULL", "") - ); - if (!tblField.leftValue().getIsNullable()) { - st.execute( - "alter table " + tblSam - + " alter column " + DBAdapterPostgres.escapeNameIfNeeded(tblField.leftValue().getName()) - + " set not null" - ); - } - } + try { + MetaTable tblMeta = (MetaTable)obj; + DBTable tbl = tblMeta.getTable(); + if (tbl == null) return; - if ( - tblField.leftValue().getDefaultValue() != null - && tblField.leftValue().getDefaultValue().length() > 0 - && !tblField.leftValue().getDefaultValue().equals(tblField.rightValue().getDefaultValue()) - ) { - st.execute("alter table " + tblSam + " alter column " + DBAdapterPostgres.escapeNameIfNeeded(tblField.leftValue().getName()) - + " SET DEFAULT " + tblField.leftValue().getDefaultValue()); - } - } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - } + String schema = getPhisicalSchema(tbl.getSchema()); - } - else { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } + freeTableSequences(tbl, connect, st); + st.execute("DROP TABLE "+adapter.escapeNameIfNeeded(schema)+"."+adapter.escapeNameIfNeeded(tbl.getName())); } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); } finally { st.close(); } } - public void restoreTableFieldsPostgres(IMetaObject obj) throws Exception - { + + public void restoreTablePostgres(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); try { if (obj instanceof MetaTable) { MetaTable restoreTable = (MetaTable)obj; - String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); - String tblName = schema+"."+restoreTable.getTable().getName(); - Map tables = adapter.getTables(schema); - boolean exist = false; - if(!(tables == null || tables.isEmpty() )) { - for(DBTable table:tables.values()) { - if(restoreTable.getTable().getName().equals(table.getName())){ - exist = true; - Map currentFileds = adapter.getTableFields(schema, restoreTable.getTable().getName()); - MapDifference diffTableFields = Maps.difference(restoreTable.getFields(),currentFileds); - - if(!diffTableFields.entriesOnlyOnLeft().isEmpty()){ - for(DBTableField tblField:diffTableFields.entriesOnlyOnLeft().values()) { - st.execute("alter table "+ tblName +" add column " + tblField.getName() + " " + tblField.getTypeSQL()); - - if (tblField.getDescription() != null && tblField.getDescription().length() > 0) - st.execute("COMMENT ON COLUMN " + tblName + "." + ((adapter.isReservedWord(tblField.getName()) || tblField.getNameExactly()) ? "\"" + tblField.getName() + "\" " : tblField.getName()) + " IS '" + tblField.getDescription() + "'"); - - if (!tblField.getIsNullable()) { - st.execute("alter table " + tblName + " alter column " + (adapter.isReservedWord(tblField.getName()) ? "\"" + tblField.getName() + "\" " : tblField.getName()) + " set not null"); - } - - if (tblField.getDefaultValue() != null && tblField.getDefaultValue().length() > 0) { - st.execute("alter table " + tblName + " alter column " + (adapter.isReservedWord(tblField.getName()) ? "\"" + tblField.getName() + "\" " : tblField.getName()) - + " SET DEFAULT " + tblField.getDefaultValue()); - } - } - } - - if(!diffTableFields.entriesOnlyOnRight().isEmpty()) { - for(DBTableField tblField:diffTableFields.entriesOnlyOnRight().values()) { - st.execute("alter table "+ tblName +" drop column IF EXISTS "+ tblField.getName()); - } - } - - if(!diffTableFields.entriesDiffering().isEmpty()) { - for(ValueDifference tblField:diffTableFields.entriesDiffering().values()) { - if(!tblField.leftValue().getName().equals(tblField.rightValue().getName())) { - st.execute("alter table "+ tblName +" rename column "+ tblField.rightValue().getName() +" to "+ tblField.leftValue().getName()); - } - - if(!tblField.leftValue().getTypeSQL().equals(tblField.rightValue().getTypeSQL())) { - st.execute("alter table "+ tblName +" alter column "+ tblField.leftValue().getName() +" type "+ tblField.leftValue().getTypeSQL()); - } - } - } - } - } - } - if(!exist){ - for(DBTableField tblField:restoreTable.getFields().values()) { - st.execute("alter table "+ tblName +" add column " + tblField.getName() + " " + tblField.getTypeSQL()); + MetaTable existingTable = new MetaTable(restoreTable.getTable()); - if (tblField.getDescription() != null && tblField.getDescription().length() > 0) - st.execute("COMMENT ON COLUMN " + tblName + "." + ((adapter.isReservedWord(tblField.getName()) || tblField.getNameExactly()) ? "\"" + tblField.getName() + "\" " : tblField.getName()) + " IS '" + tblField.getDescription() + "'"); - if (!tblField.getIsNullable()) { - st.execute("alter table " + tblName + " alter column " + (adapter.isReservedWord(tblField.getName()) ? "\"" + tblField.getName() + "\" " : tblField.getName()) + " set not null"); - } + String schema = adapter.escapeNameIfNeeded(getPhisicalSchema(restoreTable.getTable().getSchema().toLowerCase())); + String tblName = adapter.escapeNameIfNeeded(restoreTable.getTable().getName()); + String tblSam = adapter.escapeNameIfNeeded(schema) + "." + adapter.escapeNameIfNeeded(tblName); - if (tblField.getDefaultValue() != null && tblField.getDefaultValue().length() > 0) { - st.execute("alter table " + tblName + " alter column " + (adapter.isReservedWord(tblField.getName()) ? "\"" + tblField.getName() + "\" " : tblField.getName()) - + " SET DEFAULT " + tblField.getDefaultValue()); - } - } - } + //find existing table and set tablespace or create + if (existingTable.loadFromDB()){ + + restoreTableTablespace(st, restoreTable, existingTable); + restoreTableOwner(st, restoreTable, existingTable); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + + } else { + + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "createTable"), messageLevel); + createTable(st, restoreTable); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); - ResultSet rs = st.executeQuery("SELECT COUNT(*) as constraintscount FROM pg_catalog.pg_constraint r WHERE r.conrelid = '"+tblName+"'::regclass"); - rs.next(); - Integer constraintsCount = Integer.valueOf(rs.getString("constraintscount")); - if(constraintsCount.intValue()>0) { - removeTableConstraintsPostgres(obj); - } - // set primary key - for(DBConstraint tableconst: restoreTable.getConstraints().values()) { - if(tableconst.getConstraintType().equals("p")) { - st.execute("alter table "+ tblName +" add constraint "+ DBAdapterPostgres.escapeNameIfNeeded(tableconst.getName()) + " "+tableconst.getSql().replace(" " + tableconst.getSql() + ".", " " + schema + ".")); - break; - } } + + + restoreTableFields(restoreTable, existingTable, st); + restoreTableComment(restoreTable, existingTable, st); + restoreTablePartition(restoreTable, st); + } - else - { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + else { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { st.close(); @@ -322,7 +130,7 @@ public void restoreTableIndexesPostgres(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreIndex").withParams(obj.getName()), 1); + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreIndex").withParams(obj.getName()), messageLevel); try { if (obj instanceof MetaTable) { MetaTable restoreTable = (MetaTable)obj; @@ -335,16 +143,16 @@ public void restoreTableIndexesPostgres(IMetaObject obj) throws Exception { for(DBIndex ind:diffInd.entriesOnlyOnLeft().values()) { if(restoreTable.getConstraints().containsKey(ind.getName())) {continue;} st.execute(MessageFormat.format("{0} {1}" - ,ind.getSql().replace(" INDEX ", " INDEX IF NOT EXISTS ") - ,ind.getOptions().getChildren().containsKey("tablespace") ? " tablespace " + ind.getOptions().get("tablespace").getData() : "" + ,ind.getSql()/*.replace(" INDEX ", " INDEX IF NOT EXISTS ")*/ + ,ind.getOptions().getChildren().containsKey("tablespace") ? " tablespace " + ind.getOptions().get("tablespace").getData() : "" )); } for(DBIndex ind:diffInd.entriesOnlyOnRight().values()) { if(existingTable.getConstraints().containsKey(ind.getName())) continue; st.execute(MessageFormat.format("drop index if exists {0}.{1}" - , DBAdapterPostgres.escapeNameIfNeeded(schema) - , DBAdapterPostgres.escapeNameIfNeeded(ind.getName()) + , adapter.escapeNameIfNeeded(schema) + , adapter.escapeNameIfNeeded(ind.getName()) )); } @@ -353,18 +161,18 @@ public void restoreTableIndexesPostgres(IMetaObject obj) throws Exception { DBIndex existingIndex = ind.rightValue(); if(!restoreIndex.getSql().equalsIgnoreCase(existingIndex.getSql())) { st.execute(MessageFormat.format( - "DROP INDEX {0}.{1} CASCADE;\n" + "{2};\n", //TODO discuss CASCADE - DBAdapterPostgres.escapeNameIfNeeded(schema) - , DBAdapterPostgres.escapeNameIfNeeded(existingIndex.getName()) - , restoreIndex.getSql() //drop and re-create using full DDL from .getSql() + "DROP INDEX {0}.{1} CASCADE;\n" + "{2};\n", //TODO discuss CASCADE + adapter.escapeNameIfNeeded(schema) + , adapter.escapeNameIfNeeded(existingIndex.getName()) + , restoreIndex.getSql() //drop and re-create using full DDL from .getSql() )); st.execute(MessageFormat.format( - "alter index {0}.{1} set tablespace {2}" - ,DBAdapterPostgres.escapeNameIfNeeded(schema) - ,DBAdapterPostgres.escapeNameIfNeeded(restoreIndex.getName()) - ,restoreIndex.getOptions().getChildren().containsKey("tablespace") - ? restoreIndex.getOptions().get("tablespace").getData() - : "pg_default" + "alter index {0}.{1} set tablespace {2}" + ,adapter.escapeNameIfNeeded(schema) + ,adapter.escapeNameIfNeeded(restoreIndex.getName()) + ,restoreIndex.getOptions().getChildren().containsKey("tablespace") + ? restoreIndex.getOptions().get("tablespace").getData() + : "pg_default" )); } } @@ -373,15 +181,15 @@ public void restoreTableIndexesPostgres(IMetaObject obj) throws Exception { } } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } } @@ -389,76 +197,421 @@ public void restoreTableConstraintPostgres(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreConstr").withParams(obj.getName()), 1); try { if (obj instanceof MetaTable) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "restoreTableConstraints").withParams(obj.getName()), messageLevel); MetaTable restoreTable = (MetaTable)obj; MetaTable existingTable = new MetaTable(restoreTable.getTable()); existingTable.loadFromDB(); - String schema = getPhisicalSchema(restoreTable.getTable().getSchema()); + enrichWithNotNullConstraints(existingTable); + enrichWithNotNullConstraints(restoreTable); MapDifference diff = Maps.difference(existingTable.getConstraints(), restoreTable.getConstraints()); - //drop unneeded + // 0. drop unneeded for(DBConstraint constr : diff.entriesOnlyOnLeft().values()){ - st.execute(MessageFormat.format( - "alter table {0}.{1} drop constraint {2};\n" - , DBAdapterPostgres.escapeNameIfNeeded(schema) - , DBAdapterPostgres.escapeNameIfNeeded(existingTable.getTable().getName()) - , DBAdapterPostgres.escapeNameIfNeeded(constr.getName()) - )); + dropConstraint(existingTable, constr, st); } - // restore not existing - // not restore index if not exists and have the same named PK + // 1. restore not existing Set typesFirst = Sets.newHashSet("p", "u"); - Comparator pksFirstComparator = Comparator.comparing(x->!typesFirst.contains(x.getConstraintType())); - for(DBConstraint constr : diff.entriesOnlyOnRight().values().stream().sorted(pksFirstComparator).collect(Collectors.toList()) ) { - createConstraint(restoreTable, constr, st, false); + List newConstraints = diff.entriesOnlyOnRight().values().stream() + .sorted(Comparator.comparing( x -> !typesFirst.contains(x.getConstraintType()) )) + .collect(Collectors.toList()); + + for(DBConstraint constr : newConstraints) { + // * * * not restore index if not exists and have the same named PK + createConstraint(restoreTable, constr, st, false /* * */); } - //process intersects + // 2. process intersects for (ValueDifference constr : diff.entriesDiffering().values()){ - MapDifference propsDiff = Maps.difference(constr.leftValue().getOptions().getChildren(), constr.leftValue().getOptions().getChildren()); - ConsoleWriter.printlnColor("Difference in constraints: " + propsDiff.toString(), Ansi.FColor.MAGENTA, 1); + //MapDifference propsDiff = Maps.difference(constr.leftValue().getOptions().getChildren(), constr.leftValue().getOptions().getChildren()); + //ConsoleWriter.printlnColor("Difference in constraints: " + propsDiff.toString(), Ansi.FColor.MAGENTA, 1); createConstraint(restoreTable, constr.rightValue(), st, true); } - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); st.close(); } } - private void createConstraint(MetaTable restoreTable, DBConstraint constr, StatementLogging st, boolean replaceExisting) throws Exception { - String schema = getPhisicalSchema(constr.getSchema()); - String tableSam = DBAdapterPostgres.escapeNameIfNeeded(schema) + "." + DBAdapterPostgres.escapeNameIfNeeded(restoreTable.getTable().getName()); - String constrName = DBAdapterPostgres.escapeNameIfNeeded(constr.getName()); - String constrDdl = (replaceExisting) ? MessageFormat.format("alter table {0} drop constraint {1};\n", tableSam, constrName) : ""; - constrDdl += MessageFormat.format( - "alter table {0} add constraint {1} {2};\n" - ,tableSam - ,constrName - ,constr.getSql() - .replace(" " + constr.getSchema() + ".", " " + schema + ".") - .replace("REFERENCES ", "REFERENCES " + schema + ".") + private void dropConstraint(MetaTable existingTable, DBConstraint constr, StatementLogging st) throws SQLException, ExceptionDBGit { + String schema = getPhisicalSchema(existingTable.getTable().getSchema()); + String name = existingTable.getTable().getName(); + + if(constr.getConstraintType().equals("nn")){ + st.execute(MessageFormat.format( + "ALTER TABLE {0}.{1} ALTER {2} DROP NOT NULL;\n" + , adapter.escapeNameIfNeeded(schema) + , adapter.escapeNameIfNeeded(name) + , adapter.escapeNameIfNeeded(constr.getOptions().get("column_name").getData()) + )); + } else { + st.execute(MessageFormat.format( + "ALTER TABLE {0}.{1} DROP CONSTRAINT {2};\n" + , adapter.escapeNameIfNeeded(schema) + , adapter.escapeNameIfNeeded(name) + , adapter.escapeNameIfNeeded(constr.getName()) + )); + } + } + + private NameMeta getEscapedNameMeta(MetaTable table) throws ExceptionDBGit { + NameMeta nm = new NameMeta(); + String schema = adapter.escapeNameIfNeeded(getPhisicalSchema(table.getTable().getSchema().toLowerCase())); + String tblName = adapter.escapeNameIfNeeded(table.getTable().getName()); + + nm.setSchema(schema); + nm.setName(tblName); + nm.setType(DBGitMetaType.DBGitTable); + return nm; + } + + + private void restoreTableFields(MetaTable restoreTable, MetaTable existingTable, StatementLogging st) throws Exception { + String lastField = ""; + try { + NameMeta nme = getEscapedNameMeta(existingTable); + String tblSam = nme.getSchema()+"."+nme.getName(); + + MapDifference diffTableFields = Maps.difference(restoreTable.getFields(),existingTable.getFields()); + + if(!diffTableFields.entriesOnlyOnLeft().isEmpty()){ + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "addColumns"), messageLevel); + + List fields = diffTableFields.entriesOnlyOnLeft().values().stream() + .sorted(Comparator.comparing(DBTableField::getOrder)) + .collect(Collectors.toList()); + + for(DBTableField tblField : fields) { + lastField = tblField.getName(); + addColumn(tblSam, tblField, st); + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + + if(!diffTableFields.entriesOnlyOnRight().isEmpty()) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "droppingColumns"), messageLevel); + for(DBTableField tblField:diffTableFields.entriesOnlyOnRight().values()) { + lastField = tblField.getName(); + dropColumn(tblSam, tblField, st); + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + + if(!diffTableFields.entriesDiffering().isEmpty()) { + ConsoleWriter.detailsPrintln(lang.getValue("general", "restore", "modifyColumns"), messageLevel); + for(ValueDifference tblField:diffTableFields.entriesDiffering().values()) { + lastField = tblField.leftValue().getName(); + + DBTableField restoreField = tblField.leftValue(); + DBTableField existingField = tblField.rightValue(); + if( !isSameTypeSql(tblField.leftValue(), tblField.rightValue()) ) { + if( true + &&(existingField.getTypeUniversal() != FieldType.BOOLEAN) + &&(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") + ){ //Lots of exclusions when this don't work + alterTypeColumn(tblSam, tblField, st); + } else { + dropColumn(tblSam, tblField.rightValue(), st); + addColumn(tblSam, tblField.leftValue(), st); + } + } + + restoreTableFieldComment(tblSam, tblField, st); + restoreTableFieldDefaultValue(tblSam, tblField, st); + + if(!tblField.leftValue().getName().equals(tblField.rightValue().getName())) { + throw new Exception("just 'differing' columns, but differs in names, was: " + tblField.rightValue().getName() + ", to restore: " + tblField.leftValue().getName()); + // st.execute( + // "alter table " + // + tblSam + // +" rename column "+ adapter.escapeNameIfNeeded(tblField.rightValue().getName()) + // +" to "+ adapter.escapeNameIfNeeded(tblField.leftValue().getName()) + // ); + } + } + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + } + } catch (Exception e) { + throw new ExceptionDBGit( + lang.getValue("errors", "restore", "objectRestoreError").withParams(restoreTable.getName()+"#"+lastField) + , e + ); + } + } + private void createTable(StatementLogging st, MetaTable restoreTable) throws Exception { + NameMeta nme = getEscapedNameMeta(restoreTable); + + String createTableDdl = MessageFormat.format( + "create table {0}.{1}() {2};" + ,nme.getSchema() + ,nme.getName() + ,restoreTable.getTable().getOptions().getChildren().containsKey("tablespace") + ? "tablespace " + restoreTable.getTable().getOptions().get("tablespace").getData() + : "" + + ); + + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + createTableDdl += MessageFormat.format("\n alter table {0}.{1} owner to {2}\n;", + nme.getSchema() ,nme.getName(), + restoreTable.getTable().getOptions().getChildren().containsKey("owner") + ? restoreTable.getTable().getOptions().get("owner").getData() + : "postgres" + ); + } + + if (restoreTable.getTable().getOptions().getChildren().containsKey("partkeydef")) { + createTableDdl = createTableDdl.replace(" ) ", ") PARTITION BY " + + restoreTable.getTable().getOptions().getChildren().get("partkeydef") + + " "); + } + + st.execute(createTableDdl); + } + private void restoreTableOwner(StatementLogging st, MetaTable restoreTable, MetaTable existingTable) throws Exception { + String schema = adapter.escapeNameIfNeeded(getPhisicalSchema(restoreTable.getTable().getSchema().toLowerCase())); + String tblName = adapter.escapeNameIfNeeded(restoreTable.getTable().getName()); + + StringProperties exOwner= existingTable.getTable().getOptions().get("owner"); + StringProperties restoreOwner = restoreTable.getTable().getOptions().get("owner"); + + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + if(restoreOwner != null && ( exOwner == null || !exOwner.getData().equals(restoreOwner.getData()) ) ){ + String alterTableDdl = MessageFormat.format( + "alter table {0}.{1} owner to {2};\n" + ,schema + ,tblName + ,restoreTable.getTable().getOptions().get("owner").getData() + ); + st.execute(alterTableDdl); + } + } + } + private void restoreTableTablespace(StatementLogging st, MetaTable restoreTable, MetaTable existingTable) throws SQLException, ExceptionDBGit { + NameMeta nme = getEscapedNameMeta(existingTable); + + StringProperties exTablespace = existingTable.getTable().getOptions().get("tablespace"); + StringProperties restoreTablespace = restoreTable.getTable().getOptions().get("tablespace"); + if(restoreTablespace != null && + ( exTablespace == null || !exTablespace.getData().equals(restoreTablespace.getData()) ) ){ + //TODO For now in postgres context tablespace is always missing! + String alterTableDdl = MessageFormat.format( + "alter table {0}.{1} set tablespace {2};\n" + ,nme.getSchema() + ,nme.getName() + ,restoreTable.getTable().getOptions().get("tablespace").getData() + ); + st.execute(alterTableDdl); + } + } + + + //TODO removeMetaObject + private void freeTableSequences(DBTable tbl, Connection conn, StatementLogging st) throws SQLException { + Statement stService = conn.createStatement(); + ResultSet rsSequences = stService.executeQuery("SELECT n.nspname as schema, s.relname as sequence, t.relname as table\n" + + " FROM pg_class s, pg_depend d, pg_class t, pg_attribute a, pg_namespace n \n" + + " WHERE s.relkind = 'S' \n" + + " AND n.oid = s.relnamespace \n" + + " AND d.objid = s.oid \n" + + " AND d.refobjid = t.oid \n" + + " AND (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)\n" + + " AND n.nspname = '"+tbl.getSchema()+"' AND t.relname = '"+tbl.getName()+"'"); + + while (rsSequences.next()) st.execute(MessageFormat.format( + "ALTER SEQUENCE {0}.{1} OWNED BY NONE" + , rsSequences.getString("schema") + , rsSequences.getString("sequence")) ); + + stService.close(); + } + + + //TODO restoreTablePostgres + private void restoreTableComment(MetaTable restoreTable, MetaTable existingTable, Statement st) throws ExceptionDBGit, SQLException + { + + String restoreTableComment = restoreTable.getTable().getComment(); + String existingTableComment = existingTable.getTable().getComment(); + boolean restoreCommentPresent = restoreTableComment != null && restoreTableComment.length() > 0; + boolean existingCommentPresent = existingTableComment != null && existingTableComment.length() > 0; + + if (restoreCommentPresent){ + boolean commentsDiffer = !existingCommentPresent || !existingTableComment.equals(restoreTableComment); + if(commentsDiffer){ + st.execute(MessageFormat.format( + "COMMENT ON TABLE {0}.{1} IS ''{2}''" + ,adapter.escapeNameIfNeeded(getPhisicalSchema(restoreTable.getTable().getSchema())) + ,adapter.escapeNameIfNeeded(restoreTable.getTable().getName()) + ,restoreTableComment + )); + } + } + } + private void restoreTablePartition(MetaTable restoreTable, Statement st) throws ExceptionDBGit, SQLException + { + NameMeta nme = getEscapedNameMeta(restoreTable); + StringProperties parent = restoreTable.getTable().getOptions().getChildren().get("parent"); + StringProperties pg_get_expr = restoreTable.getTable().getOptions().getChildren().get("pg_get_expr"); + + if(parent != null && pg_get_expr != null){ + st.execute(MessageFormat.format( + "ALTER TABLE {0}.{1} ATTACH PARTITION {0}.{2} {3}" + , nme.getSchema() + , parent + , nme.getName() + , pg_get_expr + )); + } + + } + + + //TODO restoreTableConstraintPostgres + private void createConstraint(MetaTable restoreTable, DBConstraint constr, StatementLogging st, boolean replaceExisting) throws Exception { + //dont create constraint on table with 'parent' key + if (restoreTable.getTable().getOptions().getChildren().containsKey("parent")) return; + + NameMeta nme = getEscapedNameMeta(restoreTable); + String tblSam = getPhisicalSchema(nme.getSchema())+"."+nme.getName(); + String constrDdl; + + if(constr.getConstraintType().equals("nn")){ + constrDdl = MessageFormat.format("ALTER TABLE {0} {1};\n", tblSam, constr.getSql()); + + } else { + String constrName = adapter.escapeNameIfNeeded(constr.getName()); + + constrDdl = (replaceExisting) + ? MessageFormat.format("ALTER TABLE {0} DROP CONSTRAINT {1};\n", tblSam, constrName) + : ""; + constrDdl += MessageFormat.format( + "ALTER TABLE {0} ADD CONSTRAINT {1} {2};\n" + ,tblSam + ,constrName + ,constr.getSql() + .replace(" " + constr.getSchema() + ".", " " + nme.getSchema() + ".") + .replace("REFERENCES ", "REFERENCES " + nme.getSchema() + ".") + ); + } + st.execute(constrDdl); } - public void removeTableConstraintsPostgres(IMetaObject obj) throws Exception { + //TODO restoreTableFields + private void addColumn(String tblSam, DBTableField tblField, Statement st ) throws SQLException { + String fieldName = adapter.escapeNameIfNeeded(tblField.getName()); + st.execute( + "alter table "+ tblSam +" add column " + + fieldName + " " + + tblField.getTypeSQL().replace("NOT NULL", "") + ); + if (tblField.getDescription() != null && tblField.getDescription().length() > 0) + st.execute( + "COMMENT ON COLUMN " + tblSam + "." + + fieldName + + " IS '" + tblField.getDescription() + "'" + ); + + + if (tblField.getDefaultValue() != null && tblField.getDefaultValue().length() > 0) { + st.execute( + "alter table " + tblSam + " alter column " + fieldName + + " SET DEFAULT " + tblField.getDefaultValue() + ); + } + + } + private void dropColumn(String tblSam, DBTableField tblField, Statement st) throws SQLException { + st.execute("alter table "+ tblSam +" drop column "+ adapter.escapeNameIfNeeded(tblField.getName())); + } + private boolean isSameTypeSql(DBTableField left, DBTableField right){ + return left.getTypeSQL().equals(right.getTypeSQL()); + } + + private boolean hasNotTypeSql(ValueDifference field, String typeSql){ + return !field.leftValue().getTypeSQL().contains(typeSql) && + !field.rightValue().getTypeSQL().contains(typeSql); + } + private void alterTypeColumn(String tblSam, ValueDifference tblField, Statement st) throws SQLException + { + st.execute(MessageFormat.format("ALTER TABLE {0} ALTER COLUMN {1} TYPE {2} USING ({3}::{4})" + , tblSam + , adapter.escapeNameIfNeeded(tblField.leftValue().getName()) + //NOT NULLs are created and dropped with other constraints as transient DBConstraint instances + , tblField.leftValue().getTypeSQL().replace("NOT NULL", "") + , adapter.escapeNameIfNeeded(tblField.leftValue().getName()) + , tblField.leftValue().getTypeSQL().replace("NOT NULL", "") + )); + + } + private void restoreTableFieldComment(String tableSam, ValueDifference tblField, Statement st) throws SQLException + { + + String restoreDesc = tblField.leftValue().getDescription(); + String existingDesc = tblField.rightValue().getDescription(); + boolean restoreDescPresent = restoreDesc != null && restoreDesc.length() > 0; + + if (restoreDescPresent){ + boolean existingDescPresent = existingDesc != null && existingDesc.length() > 0; + boolean needsUpdate = !existingDescPresent || !existingDesc.equals(restoreDesc); + if(needsUpdate){ + st.execute(MessageFormat.format( + "COMMENT ON COLUMN {0}.{1} IS ''{2}''" + ,tableSam + ,adapter.escapeNameIfNeeded(tblField.leftValue().getName()) + ,restoreDesc + )); + } + } + } + private void restoreTableFieldDefaultValue(String tableSam, ValueDifference tblField, Statement st) throws ExceptionDBGit, SQLException + { + + String restoreDefault = tblField.leftValue().getDefaultValue(); + String existingDefault = tblField.rightValue().getDefaultValue(); + boolean restoreDefaultPresent = restoreDefault != null && restoreDefault.length() > 0; + + if (restoreDefaultPresent){ + boolean existingDescPresent = existingDefault != null && existingDefault.length() > 0; + boolean needsUpdate = !existingDescPresent || !existingDefault.equals(restoreDefault); + if(needsUpdate){ + st.execute(MessageFormat.format( + "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}" + ,tableSam + ,adapter.escapeNameIfNeeded(tblField.leftValue().getName()) + ,restoreDefault + )); + } + } + } + + + //TODO unused + private void removeTableIndexesPostgres(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); @@ -467,24 +620,30 @@ public void removeTableConstraintsPostgres(IMetaObject obj) throws Exception { MetaTable table = (MetaTable)obj; String schema = getPhisicalSchema(table.getTable().getSchema()); - Map constraints = table.getConstraints(); - for(DBConstraint constrs :constraints.values()) { - st.execute( - "alter table "+ DBAdapterPostgres.escapeNameIfNeeded(schema) +"."+DBAdapterPostgres.escapeNameIfNeeded(table.getTable().getName()) - +" drop constraint if exists "+DBAdapterPostgres.escapeNameIfNeeded(constrs.getName()) - ); + + Map indices = table.getIndexes(); + for(DBIndex index :indices.values()) { + if(table.getConstraints().containsKey(index.getName())) { continue; } + + st.execute(MessageFormat.format( + "DROP INDEX IF EXISTS {0}.{1}" + ,adapter.escapeNameIfNeeded(schema) +// ,adapter.escapeNameIfNeeded(table.getTable().getName()) + ,adapter.escapeNameIfNeeded(index.getName()) + )); } } else { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } } - - public void removeTableIndexesPostgres(IMetaObject obj) throws Exception { + private void removeTableConstraintsPostgres(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); @@ -492,28 +651,55 @@ public void removeTableIndexesPostgres(IMetaObject obj) throws Exception { if (obj instanceof MetaTable) { MetaTable table = (MetaTable)obj; String schema = getPhisicalSchema(table.getTable().getSchema()); + MetaTable dbTable = (MetaTable) GitMetaDataManager.getInstance().getCacheDBMetaObject(obj.getName()); - Map constraints = table.getIndexes(); - for(DBIndex constrs :constraints.values()) { - st.execute(MessageFormat.format( - "alter table {0}.{1} drop index if exists {2}" - ,DBAdapterPostgres.escapeNameIfNeeded(schema) - ,DBAdapterPostgres.escapeNameIfNeeded(table.getTable().getName()) - ,DBAdapterPostgres.escapeNameIfNeeded(constrs.getName()) - )); + enrichWithNotNullConstraints(table); + Map constraints = dbTable.getConstraints(); + for(DBConstraint constrs :constraints.values()) { + dropConstraint(table, constrs, st); } } - else - { - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + else { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "table", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()) + , e + ); } + } + + public void enrichWithNotNullConstraints(MetaTable table){ + table.getFields().values().stream() + .filter( field -> field.getIsNullable()) + .map( field -> constructNotNullDBConstraint(table, field)) + .forEach( nnc -> table.getConstraints().put(nnc.getName(), nnc) ); } - /*public void removeIndexesPostgres(IMetaObject obj) throws Exception { + public DBConstraint constructNotNullDBConstraint(MetaTable table, DBTableField field){ + final String name = "notnull_" + field.getName() + " (Transient)"; + final String type = "nn"; + final String sql = ""; + final StringProperties options = new StringProperties(); + final Set dependencies = Collections.emptySet(); + final DBTable dbTable = table.getTable(); + final String schema = dbTable.getSchema(); + final String owner = dbTable.getOwner(); + + DBConstraint constraint = new DBConstraint(name, options, schema, owner, dependencies, sql, type); + + constraint.getOptions().getChildren().put("column_name", new StringProperties(field.getName())); + constraint.setSql(MessageFormat.format( + "ALTER COLUMN {0} SET NOT NULL" + , adapter.escapeNameIfNeeded(field.getName())) + ); + return constraint; + } + + /*public void removeIndexesPostgres(IMetaObject obj) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); @@ -534,47 +720,4 @@ public void removeTableIndexesPostgres(IMetaObject obj) throws Exception { throw new ExceptionDBGitRestore("Error restore "+obj.getName(), e); } }*/ - - public void removeMetaObject(IMetaObject obj) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - - try { - MetaTable tblMeta = (MetaTable)obj; - DBTable tbl = tblMeta.getTable(); - if (tbl == null) return; - - String schema = getPhisicalSchema(tbl.getSchema()); - - freeTableSequences(tbl, connect, st); - st.execute("DROP TABLE "+DBAdapterPostgres.escapeNameIfNeeded(schema)+"."+DBAdapterPostgres.escapeNameIfNeeded(tbl.getName())); - } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); - } finally { - st.close(); - } - } - - private void freeTableSequences(DBTable tbl, Connection conn, StatementLogging st) throws SQLException { - Statement stService = conn.createStatement(); - ResultSet rsSequences = stService.executeQuery("SELECT n.nspname as schema, s.relname as sequence, t.relname as table\n" + - " FROM pg_class s, pg_depend d, pg_class t, pg_attribute a, pg_namespace n \n" + - " WHERE s.relkind = 'S' \n" + - " AND n.oid = s.relnamespace \n" + - " AND d.objid = s.oid \n" + - " AND d.refobjid = t.oid \n" + - " AND (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)\n" + - " AND n.nspname = '"+tbl.getSchema()+"' AND t.relname = '"+tbl.getName()+"'"); - - while (rsSequences.next()) st.execute(MessageFormat.format( - "ALTER SEQUENCE {0}.{1} OWNED BY NONE" - , rsSequences.getString("schema") - , rsSequences.getString("sequence")) - ); - - stService.close(); - } - } diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableSpacePostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableSpacePostgres.java index 90e83b3..51ca6e8 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableSpacePostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTableSpacePostgres.java @@ -1,89 +1,90 @@ -package ru.fusionsoft.dbgit.postgres; - -import java.sql.Connection; -import java.util.Map; - -import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.dbobjects.DBTableSpace; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaTableSpace; -import ru.fusionsoft.dbgit.statement.StatementLogging; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class DBRestoreTableSpacePostgres extends DBRestoreAdapter{ - - @Override - public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTableSpace").withParams(obj.getName()), 1); - try { - if (obj instanceof MetaTableSpace) { - MetaTableSpace restoreTableSpace = (MetaTableSpace)obj; - Map tblspaces = adapter.getTableSpaces(); - boolean exist = false; - if(!(tblspaces.isEmpty() || tblspaces == null)) { - for(DBTableSpace tblspace:tblspaces.values()) { - if(restoreTableSpace.getObjectOption().getName().equals(tblspace.getName())){ - exist = true; - - String restorename = restoreTableSpace.getObjectOption().getName(); - String restoreowner = restoreTableSpace.getObjectOption().getOptions().getChildren().get("usename").getData(); - String restoreloc = restoreTableSpace.getObjectOption().getOptions().getChildren().get("pg_tablespace_location").getData(); - - st.execute("alter tablespace "+ restorename +" reset (seq_page_cost, random_page_cost, effective_io_concurrency)"); - - String currentname = tblspace.getName(); - String currentowner = tblspace.getOptions().getChildren().get("usename").getData(); - String currentloc = tblspace.getOptions().getChildren().get("pg_tablespace_location").getData(); - - if(!restoreowner.equals(currentowner)) { - st.execute("alter tablespace "+ restorename +" owner to "+ restoreowner); - } - - if(restoreTableSpace.getObjectOption().getOptions().getChildren().containsKey("spcoptions")) { - String options = restoreTableSpace.getObjectOption().getOptions().getChildren().get("spcoptions").getData().replaceAll("[\\{\\}]", ""); - st.execute("alter tablespace "+ restorename +" set ("+ options+")"); - } - - - /*if() { - //TODO Restore location ??? - }*/ - //TODO Восстановление привилегий - } - } - } - if(!exist){ - - //TODO Восстановление привилегий - } - else { - - } - } - else - { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - st.close(); - } - return true; - } - - @Override - public void removeMetaObject(IMetaObject obj) throws Exception { - // TODO Auto-generated method stub - - } - -} +package ru.fusionsoft.dbgit.postgres; + +import java.sql.Connection; +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.DBTableSpace; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaTableSpace; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class DBRestoreTableSpacePostgres extends DBRestoreAdapter{ + + @Override + public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + try { + if (obj instanceof MetaTableSpace) { + MetaTableSpace restoreTableSpace = (MetaTableSpace)obj; + Map tblspaces = adapter.getTableSpaces(); + boolean exist = false; + if(!(tblspaces.isEmpty() || tblspaces == null)) { + for(DBTableSpace tblspace:tblspaces.values()) { + if(restoreTableSpace.getObjectOption().getName().equals(tblspace.getName())){ + exist = true; + + String restorename = restoreTableSpace.getObjectOption().getName(); + String restoreowner = restoreTableSpace.getObjectOption().getOptions().getChildren().get("usename").getData(); + String restoreloc = restoreTableSpace.getObjectOption().getOptions().getChildren().get("pg_tablespace_location").getData(); + + st.execute("alter tablespace "+ restorename +" reset (seq_page_cost, random_page_cost, effective_io_concurrency)"); + + String currentname = tblspace.getName(); + String currentowner = tblspace.getOptions().getChildren().get("usename").getData(); + String currentloc = tblspace.getOptions().getChildren().get("pg_tablespace_location").getData(); + + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false) && !restoreowner.equals(currentowner)) { + st.execute("alter tablespace "+ restorename +" owner to "+ restoreowner); + } + + if(restoreTableSpace.getObjectOption().getOptions().getChildren().containsKey("spcoptions")) { + String options = restoreTableSpace.getObjectOption().getOptions().getChildren().get("spcoptions").getData().replaceAll("[\\{\\}]", ""); + st.execute("alter tablespace "+ restorename +" set ("+ options+")"); + } + + + /*if() { + //TODO Restore location ??? + }*/ + //TODO Восстановление привилегий + } + } + } + if(!exist){ + + //TODO Восстановление привилегий + } + else { + + } + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "tablespace", obj.getType().getValue() + )); + } + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } finally { + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + st.close(); + } + return true; + } + + @Override + public void removeMetaObject(IMetaObject obj) throws Exception { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTriggerPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTriggerPostgres.java index fe7ba11..82bd4e3 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTriggerPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreTriggerPostgres.java @@ -1,100 +1,96 @@ -package ru.fusionsoft.dbgit.postgres; - -import java.sql.Connection; -import java.util.Map; - -import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; -import ru.fusionsoft.dbgit.adapters.IDBAdapter; -import ru.fusionsoft.dbgit.core.ExceptionDBGit; -import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.dbobjects.DBTrigger; -import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaTrigger; -import ru.fusionsoft.dbgit.statement.StatementLogging; -import ru.fusionsoft.dbgit.utils.ConsoleWriter; - -public class DBRestoreTriggerPostgres extends DBRestoreAdapter { - - - @Override - public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreTrigger").withParams(obj.getName()), 1); - try { - if (obj instanceof MetaTrigger) { - MetaTrigger restoreTrigger = (MetaTrigger)obj; - Map trgs = adapter.getTriggers(restoreTrigger.getSqlObject().getSchema()); - boolean exist = false; - if(!(trgs.isEmpty() || trgs == null)) { - for(DBTrigger trg:trgs.values()) { - if(restoreTrigger.getSqlObject().getName().equals(trg.getName())){ - exist = true; - if(!restoreTrigger.getSqlObject().getSql().equals(trg.getSql())) { - String query = "DROP TRIGGER IF EXISTS "+restoreTrigger.getSqlObject().getName()+" ON "+restoreTrigger.getSqlObject().getOptions().get("trigger_table")+";\n"; - query+=restoreTrigger.getSqlObject().getSql()+";"; - st.execute(query); - } - //TODO Восстановление привилегий - } - } - } - if(!exist){ - st.execute(restoreTrigger.getSqlObject().getSql()); - //TODO Восстановление привилегий - } - } - else - { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); - } - - - - - } - catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); - } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); - st.close(); - } - - - - - - - - - - return true; - } - - @Override - public void removeMetaObject(IMetaObject obj) throws Exception { - IDBAdapter adapter = getAdapter(); - Connection connect = adapter.getConnection(); - StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - - try { - if(! (obj instanceof MetaTrigger)) throw new ExceptionDBGit("Wrong IMetaObject type, expected: trg, was: " + obj.getType().getValue()); - MetaTrigger trgMeta = (MetaTrigger) obj; - DBTrigger trg = (DBTrigger) trgMeta.getSqlObject(); - if (trg == null) return; - - String schema = getPhisicalSchema(trg.getSchema()); - st.execute("DROP FUNCTION IF EXISTS "+DBAdapterPostgres.escapeNameIfNeeded(schema)+"."+DBAdapterPostgres.escapeNameIfNeeded(trg.getName())); - - } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); - } finally { - st.close(); - } - } - -} +package ru.fusionsoft.dbgit.postgres; + +import java.sql.Connection; +import java.util.Map; + +import ru.fusionsoft.dbgit.adapters.DBRestoreAdapter; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; +import ru.fusionsoft.dbgit.dbobjects.DBTrigger; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.meta.MetaTrigger; +import ru.fusionsoft.dbgit.statement.StatementLogging; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +public class DBRestoreTriggerPostgres extends DBRestoreAdapter { + + + @Override + public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + try { + if (obj instanceof MetaTrigger) { + MetaTrigger restoreTrigger = (MetaTrigger)obj; + Map trgs = adapter.getTriggers(restoreTrigger.getSqlObject().getSchema()); + boolean exist = false; + if(!(trgs.isEmpty() || trgs == null)) { + for(DBTrigger trg:trgs.values()) { + if(restoreTrigger.getSqlObject().getName().equals(trg.getName())){ + exist = true; + if(!restoreTrigger.getSqlObject().getSql().equals(trg.getSql())) { + String query = "DROP TRIGGER IF EXISTS "+restoreTrigger.getSqlObject().getName()+" ON "+restoreTrigger.getSqlObject().getOptions().get("trigger_table")+";\n"; + query+=restoreTrigger.getSqlObject().getSql()+";"; + st.execute(query); + } + //TODO Восстановление привилегий + } + } + } + if(!exist){ + st.execute(restoreTrigger.getSqlObject().getSql()); + //TODO Восстановление привилегий + } + } + else + { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "trigger", obj.getType().getValue() + )); + } + + } + catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + } finally { + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); + st.close(); + } + + + + + + + + + + return true; + } + + @Override + public void removeMetaObject(IMetaObject obj) throws Exception { + IDBAdapter adapter = getAdapter(); + Connection connect = adapter.getConnection(); + StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); + + try { + if(! (obj instanceof MetaTrigger)) throw new ExceptionDBGit("Wrong IMetaObject type, expected: trg, was: " + obj.getType().getValue()); + MetaTrigger trgMeta = (MetaTrigger) obj; + DBTrigger trg = (DBTrigger) trgMeta.getSqlObject(); + if (trg == null) return; + + String schema = getPhisicalSchema(trg.getSchema()); + st.execute("DROP FUNCTION IF EXISTS "+adapter.escapeNameIfNeeded(schema)+"."+adapter.escapeNameIfNeeded(trg.getName())); + + } catch (Exception e) { + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); + } finally { + st.close(); + } + } + +} 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/DBRestoreUserPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreUserPostgres.java index 44b24a5..7f1844a 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreUserPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreUserPostgres.java @@ -17,7 +17,6 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreUser").withParams(obj.getName()), 1); try { if (obj instanceof MetaUser) { MetaUser usr = (MetaUser)obj; @@ -25,14 +24,15 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "user", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreViewPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreViewPostgres.java index 6029966..ba9562e 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreViewPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/DBRestoreViewPostgres.java @@ -1,16 +1,16 @@ 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.ExceptionDBGit; import ru.fusionsoft.dbgit.core.ExceptionDBGitRestore; -import ru.fusionsoft.dbgit.dbobjects.DBTable; import ru.fusionsoft.dbgit.dbobjects.DBView; import ru.fusionsoft.dbgit.meta.IMetaObject; -import ru.fusionsoft.dbgit.meta.MetaTable; import ru.fusionsoft.dbgit.meta.MetaView; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; @@ -22,58 +22,50 @@ public boolean restoreMetaObject(IMetaObject obj, int step) throws Exception { IDBAdapter adapter = getAdapter(); Connection connect = adapter.getConnection(); StatementLogging st = new StatementLogging(connect, adapter.getStreamOutputSqlCommand(), adapter.isExecSql()); - ConsoleWriter.detailsPrint(lang.getValue("general", "restore", "restoreView").withParams(obj.getName()), 1); try { if (obj instanceof MetaView) { - MetaView restoreView = (MetaView)obj; + MetaView restoreView = (MetaView)obj; Map views = adapter.getViews(restoreView.getSqlObject().getSchema()); boolean exist = false; - if(!(views.isEmpty() || views == null)) { + if(! (views == null || views.isEmpty())) { for(DBView vw:views.values()) { if(restoreView.getSqlObject().getName().equals(vw.getName())){ exist = true; if(!restoreView.getSqlObject().getSql().equals(vw.getSql())) { - //String ss = "CREATE OR REPLACE VIEW "+restoreView.getSqlObject().getName() +" AS\n"+restoreView.getSqlObject().getSql(); - st.execute(restoreView.getSqlObject().getName() +" AS\n"+restoreView.getSqlObject().getSql()); + st.execute(getDdlEscaped(restoreView)); } - - if(!restoreView.getSqlObject().getOwner().equals(vw.getOwner())) { - st.execute("ALTER VIEW "+restoreView.getSqlObject().getName() +" OWNER TO "+restoreView.getSqlObject().getOwner()); + + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + if(!restoreView.getSqlObject().getOwner().equals(vw.getOwner())) { + st.execute(getChangeOwnerDdl(restoreView, restoreView.getSqlObject().getOwner())); + } } - //TODO Восстановление привилегий } } } if(!exist){ - String query = restoreView.getSqlObject().getSql(); - String name = restoreView.getSqlObject().getName(); - boolean nameShouldBeEscaped = name.contains(".") || Character.isUpperCase(name.codePointAt(0)); - if (nameShouldBeEscaped) { - query = query.replace( - "create or replace view " + restoreView.getSqlObject().getSchema() + "." + restoreView.getSqlObject().getName(), - "create or replace view " + restoreView.getSqlObject().getSchema() + ".\"" + restoreView.getSqlObject().getName() + "\""); + String query = getDdlEscaped(restoreView); + if(!DBGitConfig.getInstance().getToIgnoreOnwer(false)){ + query += getChangeOwnerDdl(restoreView, restoreView.getSqlObject().getOwner()); } - - if (!query.endsWith(";")) query = query + ";"; - query = query + "\n"; - - query+= "ALTER VIEW "+ restoreView.getSqlObject().getSchema() + "." - + ( nameShouldBeEscaped ?( "\"" + name + "\"") : name) - + " OWNER TO "+restoreView.getSqlObject().getOwner()+";\n"; st.execute(query); - //TODO Восстановление привилегий } + //TODO Восстановление привилегий ? } else { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName())); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "metaTypeError").withParams( + obj.getName() + , "view", obj.getType().getValue() + )); } } catch (Exception e) { - ConsoleWriter.detailsPrintlnRed(lang.getValue("errors", "meta", "fail")); - throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError").withParams(obj.getName()), e); + throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRestoreError") + .withParams(obj.getName()) + , e + ); } finally { - ConsoleWriter.detailsPrintlnGreen(lang.getValue("general", "ok")); + ConsoleWriter.detailsPrintGreen(lang.getValue("general", "ok")); st.close(); } return true; @@ -92,13 +84,37 @@ public void removeMetaObject(IMetaObject obj) throws Exception { if (vw == null) return; String schema = getPhisicalSchema(vw.getSchema()); - st.execute("DROP VIEW "+DBAdapterPostgres.escapeNameIfNeeded(schema)+"."+DBAdapterPostgres.escapeNameIfNeeded(vw.getName())); + st.execute("DROP VIEW "+adapter.escapeNameIfNeeded(schema)+"."+adapter.escapeNameIfNeeded(vw.getName())); } catch (Exception e) { - ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage())); + ConsoleWriter.println(lang.getValue("errors", "restore", "objectRestoreError").withParams(e.getLocalizedMessage()),0); throw new ExceptionDBGitRestore(lang.getValue("errors", "restore", "objectRemoveError").withParams(obj.getName()), e); } finally { st.close(); } } + private String getDdlEscaped(MetaView view){ + String name = view.getSqlObject().getName(); + String schema = view.getSqlObject().getSchema(); + String query = view.getSqlObject().getSql(); + String nameEscaped = adapter.escapeNameIfNeeded(name); + + if (!name.equalsIgnoreCase(nameEscaped)) { + query = query.replace( + "create or replace view " + schema + "." + name, + "create or replace view " + schema + "." + nameEscaped + ); + } + if (!query.endsWith(";")) query = query + ";\n"; + query = query + "\n"; + return query; + } + + private String getChangeOwnerDdl(MetaView view, String owner){ + return MessageFormat.format("ALTER VIEW {0}.{1} OWNER TO {2}\n" + , view.getSqlObject().getSchema() + , adapter.escapeNameIfNeeded(view.getSqlObject().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 bb4e8c3..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()); @@ -44,7 +47,7 @@ public class FactoryDBAdapterRestorePostgres implements IFactoryDBAdapterRestote public IDBAdapterRestoreMetaData getAdapterRestore(IDBGitMetaType tp, IDBAdapter adapter) { if (!restoreAdapters.containsKey(tp.getValue())) { //return new DBRestoreMetaNotSupport(); - ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "restore", "cannotRestore").withParams(tp.getValue())); + ConsoleWriter.println(DBGitLang.getInstance().getValue("errors", "restore", "cannotRestore").withParams(tp.getValue()), messageLevel); return null; } diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/FactoryDbConvertAdapterPostgres.java b/src/main/java/ru/fusionsoft/dbgit/postgres/FactoryDbConvertAdapterPostgres.java index 76b6d8e..08bdc62 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/FactoryDbConvertAdapterPostgres.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/FactoryDbConvertAdapterPostgres.java @@ -6,9 +6,11 @@ import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.meta.DBGitMetaType; import ru.fusionsoft.dbgit.oracle.converters.TableConverterOracle; +import ru.fusionsoft.dbgit.postgres.converters.BypassVersionConverterPostgresql; import ru.fusionsoft.dbgit.postgres.converters.TableConverterPostgresql; import ru.fusionsoft.dbgit.postgres.converters.TableDataConverterPostgresql; import ru.fusionsoft.dbgit.utils.ConsoleWriter; @@ -21,6 +23,11 @@ public class FactoryDbConvertAdapterPostgres implements IFactoryDBConvertAdapter Map aMap = new HashMap(); aMap.put(DBGitMetaType.DBGitTable.getValue(), new TableConverterPostgresql()); aMap.put(DBGitMetaType.DbGitTableData.getValue(), new TableDataConverterPostgresql()); + aMap.put(DBGitMetaType.DBGitSequence.getValue(), new BypassVersionConverterPostgresql()); +// aMap.put(DBGitMetaType.DBGit.getValue(), new BypassVersionConverterPostgresql()); +// aMap.put(DBGitMetaType.DBGit.getValue(), new BypassVersionConverterPostgresql()); +// aMap.put(DBGitMetaType.DBGit.getValue(), new BypassVersionConverterPostgresql()); +// aMap.put(DBGitMetaType.DBGit.getValue(), new BypassVersionConverterPostgresql()); converters = Collections.unmodifiableMap(aMap); } @@ -28,7 +35,11 @@ public class FactoryDbConvertAdapterPostgres implements IFactoryDBConvertAdapter @Override public IDBConvertAdapter getConvertAdapter(String objectType) throws Exception { if (!converters.containsKey(objectType)) { - ConsoleWriter.detailsPrintlnRed("DBAdapterPostgres cannot convert " + objectType + "!"); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("errors", "convert", "cannotConvert") + .withParams(objectType) + , 1 + ); return null; } else return converters.get(objectType); diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/converters/BypassVersionConverterPostgresql.java b/src/main/java/ru/fusionsoft/dbgit/postgres/converters/BypassVersionConverterPostgresql.java new file mode 100644 index 0000000..b98b233 --- /dev/null +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/converters/BypassVersionConverterPostgresql.java @@ -0,0 +1,24 @@ +package ru.fusionsoft.dbgit.postgres.converters; + +import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; +import ru.fusionsoft.dbgit.core.ExceptionDBGit; +import ru.fusionsoft.dbgit.core.db.DbType; +import ru.fusionsoft.dbgit.meta.IMetaObject; + +import java.text.MessageFormat; + +public class BypassVersionConverterPostgresql implements IDBConvertAdapter { + @Override + public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) throws ExceptionDBGit { + DbType objDbType = obj.getDbType(); + if (dbType == objDbType){ + return obj; + } else { + throw new ExceptionDBGit(MessageFormat.format("Cannot convert {0} from other db type ({1} {2})" + , obj.getName() + , obj.getDbType() + , obj.getDbVersionNumber() + )); + } + } +} diff --git a/src/main/java/ru/fusionsoft/dbgit/postgres/converters/TableConverterPostgresql.java b/src/main/java/ru/fusionsoft/dbgit/postgres/converters/TableConverterPostgresql.java index 47c841d..9bdfd61 100644 --- a/src/main/java/ru/fusionsoft/dbgit/postgres/converters/TableConverterPostgresql.java +++ b/src/main/java/ru/fusionsoft/dbgit/postgres/converters/TableConverterPostgresql.java @@ -5,6 +5,7 @@ import ru.fusionsoft.dbgit.adapters.IDBConvertAdapter; import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; +import ru.fusionsoft.dbgit.core.DBGitLang; import ru.fusionsoft.dbgit.core.ExceptionDBGit; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.dbobjects.DBConstraint; @@ -25,9 +26,12 @@ public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) thr if (obj instanceof MetaTable) { MetaTable table = (MetaTable) obj; - - ConsoleWriter.println("Processing table " + table.getName()); - + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "processingTable") + .withParams(table.getName()) + , messageLevel + ); + //types for (DBTableField field : table.getFields().values()) field.setTypeSQL(typeFromAnotherDB(objDbType, field)); @@ -54,26 +58,38 @@ public IMetaObject convert(DbType dbType, String dbVersion, IMetaObject obj) thr } private String indexFromOracle(DBIndex index) { - ConsoleWriter.println("Converting table index " + index.getName() + " from oracle to postgresql..."); - + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingIndex") + .withParams(index.getName(), "oracle", "postgresql") + , messageLevel + ); + return ""; } private String constraintFromOracle(DBConstraint constraint) { - ConsoleWriter.println("Converting table constraint " + constraint.getName() + " from oracle to postgresql..."); - - Pattern patternConstraint = Pattern.compile("(?<=" + constraint.getName() + ")(.*?)(?=\\))", Pattern.MULTILINE); - Matcher matcher = patternConstraint.matcher(constraint.getSql()); - - if (matcher.find()) { - return matcher.group().replace("\"", "") + ")"; - } else { - return ""; - } + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingConstraint") + .withParams(constraint.getName(), "oracle", "postgresql") + , messageLevel + ); + + Pattern patternConstraint = Pattern.compile("(?<=" + constraint.getName() + ")(.*?)(?=\\))", Pattern.MULTILINE); + Matcher matcher = patternConstraint.matcher(constraint.getSql()); + + if (matcher.find()) { + return matcher.group().replace("\"", "") + ")"; + } else { + return ""; + } } private String typeFromAnotherDB(DbType dbType, DBTableField field) { - ConsoleWriter.println("Converting table field " + field.getName() + " from " + dbType.toString().toLowerCase() + " to postgresql..."); + ConsoleWriter.println(DBGitLang.getInstance() + .getValue("general", "convert", "convertingField") + .withParams(field.getName(), dbType.toString(), "postgresql") + , messageLevel + ); String result = ""; switch (field.getTypeUniversal()) { case STRING: diff --git a/src/main/java/ru/fusionsoft/dbgit/utils/CalcHash.java b/src/main/java/ru/fusionsoft/dbgit/utils/CalcHash.java index 5b2b499..3f65270 100644 --- a/src/main/java/ru/fusionsoft/dbgit/utils/CalcHash.java +++ b/src/main/java/ru/fusionsoft/dbgit/utils/CalcHash.java @@ -56,7 +56,14 @@ public CalcHash addDataFile(String filename) throws Exception { stream.close(); return this; } - + + public CalcHash addData(boolean data){ + return addData(String.valueOf(data)); + } + + public CalcHash addData(int data){ + return addData(String.valueOf(data)); + } public CalcHash addData(String data) { try { diff --git a/src/main/java/ru/fusionsoft/dbgit/utils/ConsoleWriter.java b/src/main/java/ru/fusionsoft/dbgit/utils/ConsoleWriter.java index 701cf7f..a310377 100644 --- a/src/main/java/ru/fusionsoft/dbgit/utils/ConsoleWriter.java +++ b/src/main/java/ru/fusionsoft/dbgit/utils/ConsoleWriter.java @@ -1,132 +1,119 @@ -package ru.fusionsoft.dbgit.utils; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; - -import com.diogonunes.jcdp.color.ColoredPrinter; -import com.diogonunes.jcdp.color.api.Ansi.Attribute; -import com.diogonunes.jcdp.color.api.Ansi.BColor; -import com.diogonunes.jcdp.color.api.Ansi.FColor; - -public class ConsoleWriter { - private static Logger logger = LoggerUtil.getLogger(ConsoleWriter.class); - private static ColoredPrinter cp = new ColoredPrinter.Builder(1, false).build(); - private static boolean showDetailedLog = false; - - - public static void detailsPrintLn(Object msg) { - if (showDetailedLog) - println(msg.toString()); - } - - public static void detailsPrint(Object msg, int level) { - if (showDetailedLog) - print(msg.toString(), level); - } - - public static void detailsPrintlnGreen(Object msg) { - if (showDetailedLog) - printlnColor(msg.toString(), FColor.GREEN, 0); - } - - public static void detailsPrintlnRed(Object msg) { - if (showDetailedLog) - printlnColor(msg.toString(), FColor.RED, 0); - } - - public static void printlnGreen(Object msg) { - printlnColor(msg.toString(), FColor.GREEN, 0); - } - - public static void printlnRed(Object msg) { - printlnColor(msg.toString(), FColor.RED, 0); - } - - public static void detailsPrintLn(String msg) { - if (showDetailedLog) - println(msg); - } - - public static void detailsPrint(String msg, int level) { - if (showDetailedLog) - print(msg, level); - } - - public static void detailsPrintlnGreen(String msg) { - if (showDetailedLog) - printlnColor(msg, FColor.GREEN, 0); - } - - public static void detailsPrintlnRed(String msg) { - if (showDetailedLog) - printlnColor(msg, FColor.RED, 0); - } - - public static void printlnGreen(String msg) { - printlnColor(msg, FColor.GREEN, 0); - } - - public static void printlnRed(String msg) { - printlnColor(msg, FColor.RED, 0); - } - - public static void printlnColor(String msg, FColor color, Integer level) { - String tab = StringUtils.leftPad("", 4*level, " "); - /* - System.out.println(tab + msg); - if (1==1) return ; - */ - cp.println(tab+msg, Attribute.NONE, color, BColor.BLACK); - cp.clear(); - //logger.info(msg); - } - - public static void printColor(String msg, FColor color, Integer level) { - String tab = StringUtils.leftPad("", 4*level, " "); - /* - System.out.println(tab + msg); - if (1==1) return ; - */ - cp.print(tab+msg, Attribute.NONE, color, BColor.BLACK); - cp.clear(); - //logger.info(msg); - } - - public static void println(Object msg) { - println(msg.toString(), 0); - } - - public static void println(String msg) { - println(msg, 0); - } - - public static void println(String msg, Integer level) { - String tab = StringUtils.leftPad("", 4*level, " "); - /* - System.out.println(tab + msg); - if (1==1) return ; - */ - cp.println(tab+msg); - cp.clear(); - //logger.info(msg); - } - - public static void print(String msg, Integer level) { - String tab = StringUtils.leftPad("", 4*level, " "); - /* - System.out.println(tab + msg); - if (1==1) return ; - */ - cp.print(tab+msg); - cp.clear(); - //logger.info(msg); - } - - public static void setDetailedLog(boolean toShowLog) { - showDetailedLog = toShowLog; - } - - public static boolean getDetailedLog() { - return showDetailedLog; - } -} +package ru.fusionsoft.dbgit.utils; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; + +import com.diogonunes.jcdp.color.ColoredPrinter; +import com.diogonunes.jcdp.color.api.Ansi.Attribute; +import com.diogonunes.jcdp.color.api.Ansi.BColor; +import com.diogonunes.jcdp.color.api.Ansi.FColor; + +import java.text.MessageFormat; + +public class ConsoleWriter { + private static Logger logger = LoggerUtil.getLogger(ConsoleWriter.class); + private static ColoredPrinter cp = new ColoredPrinter.Builder(1, false).build(); + private static boolean showDetailedLog = false; + + + public static void print(Object message, FColor color, int level, boolean newLine, boolean onlyDetailed){ + if(onlyDetailed && !showDetailedLog) return; + + String tab = StringUtils.leftPad("", 4*level, " "); + String msg = MessageFormat.format("{0}{1}", + tab, + message.toString() + ); + System.out.print(( newLine ? "\n" : " " ) + msg ); +// cp.print(msg, Attribute.NONE, color, BColor.BLACK); +// cp.clear(); + + } + + public static void setDetailedLog(boolean toShowLog) { + showDetailedLog = toShowLog; + } + public static boolean getDetailedLog() { + return showDetailedLog; + } + + // Just print + // With no color, with color and with hardcoded colors + // - no levels cause them mean nothing without a newline + + public static void print(Object msg){ + print(msg, FColor.WHITE, 0, false, false); + } + + public static void printColor(Object msg, FColor color) { + print(msg, color, 0, false, false); + } + + public static void printGreen(Object msg) { + print(msg, FColor.GREEN, 0, false, false); + } + + public static void printRed(Object msg) { + print(msg, FColor.RED, 0, false, false); + } + + // Print with a newline + // With no color, with color and with hardcoded colors + // - with explicit level + + public static void printLineBreak(){println("", 0);} + + public static void println(Object msg, Integer level) { + print(msg, FColor.WHITE, level, true, false); + } + + public static void printlnColor(Object msg, FColor color, Integer level) { + print(msg, color, level, true, false); + } + + public static void printlnGreen(Object msg, int level) { + print(msg, FColor.GREEN, level, true, false); + } + + public static void printlnRed(Object msg, int level) { + print(msg, FColor.RED, level, true, false); + } + + + // Detailed versions of other methods + // - print if only showDetailedLog is true + + public static void detailsPrint(Object msg){ + print(msg, FColor.WHITE, 0, false, true); + } + + public static void detailsPrintColor(Object msg, FColor color) { + print(msg, color, 0, false, true); + } + + public static void detailsPrintGreen(Object msg) { + print(msg, FColor.GREEN, 0, false, true); + } + + public static void detailsPrintRed(Object msg) { + print(msg, FColor.RED, 0, false, true); + } + + public static void detailsPrintln(Object msg, Integer level) { + print(msg, FColor.WHITE, level, true, true); + } + + public static void detailsPrintlnColor(Object msg, FColor color, Integer level) { + print(msg, color, level, true, true); + } + + public static void detailsPrintlnGreen(Object msg, int level) { + print(msg, FColor.GREEN, level, true, true); + } + + public static void detailsPrintlnRed(Object msg, int level) { + print(msg, FColor.RED, level, true, true); + } + + +} diff --git a/src/main/java/ru/fusionsoft/dbgit/utils/StringProperties.java b/src/main/java/ru/fusionsoft/dbgit/utils/StringProperties.java index a71b179..da14dd2 100644 --- a/src/main/java/ru/fusionsoft/dbgit/utils/StringProperties.java +++ b/src/main/java/ru/fusionsoft/dbgit/utils/StringProperties.java @@ -1,10 +1,12 @@ package ru.fusionsoft.dbgit.utils; -import java.util.HashMap; +import java.sql.ResultSet; import java.util.Map; +import java.util.Objects; import java.util.TreeMap; import org.apache.commons.lang3.StringUtils; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; /** * Tree string properties @@ -13,44 +15,60 @@ * */ public class StringProperties { - private String data = null; - private StringProperties parent = null; - private Map children = null; + private String data; + private Map children; public StringProperties() { - this.children = new TreeMap(); + this.children = new TreeMap<>(); + this.data = ""; } - public StringProperties(String data) { - this(); - this.data = data; + public StringProperties(String data) { + this.children = new TreeMap<>(); + this.data = data; } - - - public StringProperties addChild(String name) { - StringProperties childNode = new StringProperties(); - childNode.parent = this; - this.children.put(name, childNode); - return childNode; + public StringProperties(Map children) { + this.children = children == null ? new TreeMap<>() : children; + this.data = ""; } + + public StringProperties(ResultSet rs) { + this.children = new TreeMap<>(); + this.data = ""; + try { + final int columnCount = rs.getMetaData().getColumnCount(); + for (int i = 1; i <= columnCount; i++) { + + final String columnName = rs.getMetaData().getColumnName(i); + final String columnValue = rs.getString(i); + + if (columnName.equalsIgnoreCase("dependencies")) continue ; + if (columnValue == null) continue ; + + final String cleanValue = cleanString(columnValue); + final String cleanName = columnName.toLowerCase(); + + addChild(cleanName, cleanValue); + } + } catch(Exception e) { + throw new ExceptionDBGitRunTime(e); + } + } + - public StringProperties addChild(String name, StringProperties properties) { - this.children.put(name, properties); - properties.parent = this; - return properties; + public void addChild(String name, String stringValue) { + StringProperties valueOnlyNode = new StringProperties(stringValue); + this.children.put(name, valueOnlyNode); } - public StringProperties addChild(String name, String val) { - StringProperties childNode = addChild(name); - childNode.setData(val); - return childNode; + public void addChild(String name, StringProperties value) { + this.children.put(name, value); } - public StringProperties deleteChild(String name) { + public void deleteChild(String name) { if (children.containsKey(name)) { children.remove(name); } - return this; } public StringProperties xPath(String path) { @@ -75,10 +93,6 @@ public void setData(String data) { this.data = data; } - public StringProperties getParent() { - return parent; - } - public Map getChildren() { return children; } @@ -116,6 +130,34 @@ public String toString() { return toString(0).toString(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + StringProperties that = (StringProperties) o; + if(getData() != null){ + return getData().equals(that.getData()) + && Objects.equals(getChildren(), that.getChildren()); + } else { + return that.getData() == null + && Objects.equals(getChildren(), that.getChildren()); + } + + + } + + @Override + public int hashCode() { + return Objects.hash(getData(), getChildren()); + } + + public String cleanString(String str) { + String dt = str.replace("\r\n", "\n"); + while (dt.contains(" \n")) dt = dt.replace(" \n", "\n"); + dt = dt.replace("\t", " ").trim(); + + return dt; + } } diff --git a/src/main/java/ru/fusionsoft/dbgit/yaml/DBGitYamlConstructor.java b/src/main/java/ru/fusionsoft/dbgit/yaml/DBGitYamlConstructor.java index 337a8da..45aa766 100644 --- a/src/main/java/ru/fusionsoft/dbgit/yaml/DBGitYamlConstructor.java +++ b/src/main/java/ru/fusionsoft/dbgit/yaml/DBGitYamlConstructor.java @@ -9,8 +9,8 @@ import org.yaml.snakeyaml.nodes.MappingNode; import org.yaml.snakeyaml.nodes.Node; import org.yaml.snakeyaml.nodes.ScalarNode; -import org.yaml.snakeyaml.nodes.Tag; +import ru.fusionsoft.dbgit.core.ExceptionDBGitRunTime; import ru.fusionsoft.dbgit.utils.StringProperties; /** @@ -46,34 +46,31 @@ private class ConstructYamlStringProperties extends AbstractConstruct { @Override public Object construct(Node node) { if (node instanceof MappingNode) { - Object obj = constructMapping((MappingNode)node); - - StringProperties properties = new StringProperties(); - parseMap(properties, obj); - - return properties; + + final Map map = constructMapping((MappingNode)node); + return fromTreeNode(map); } if (node instanceof ScalarNode) { - //TODO - StringProperties properties = new StringProperties(); - - return properties; - } - return null; - } - - @SuppressWarnings("unchecked") - public void parseMap(StringProperties pr, Object obj) { - if (obj instanceof Map) { - Map map = (Map)obj; - for( String key : map.keySet()) { - StringProperties newPr = (StringProperties)pr.addChild(key); - parseMap(newPr, map.get(key)); - } - } else { - pr.setData((String)obj); + final String stringValue = constructScalar((ScalarNode)node).toString(); + return new StringProperties(stringValue); } + + throw new ExceptionDBGitRunTime("return null in construct! Gotcha!"); +// return null; } + + public StringProperties fromTreeNode(Object treeNode) { + try { + final Map map = (Map) treeNode; + final StringProperties constructedNode = new StringProperties(); + + map.forEach((key, value) -> constructedNode.addChild(key, fromTreeNode(value))); + return constructedNode; + + } catch (ClassCastException e) { + return new StringProperties(treeNode.toString()); + } + } } } \ No newline at end of file diff --git a/src/main/resources/lang/eng.yaml b/src/main/resources/lang/eng.yaml index b26595b..1a3e5db 100644 --- a/src/main/resources/lang/eng.yaml +++ b/src/main/resources/lang/eng.yaml @@ -3,6 +3,10 @@ general: done: Done! time: Time... {0} ms addToGit: Adding to git... + commandSuccess: Execute command success! + showDbCredentials: "Getting database connection credentials... {0}://{1}@{2}{3}" + gettingRepoLink: Getting link to repo... + repoLink: "Link: {0}" add: processingObject: Processing object {0} savingToFile: Saving to file... @@ -11,13 +15,16 @@ general: size: portion size loading: Loading portion index link: - connectionEstablished: Connection established + connectionEstablished: Testing connection OK... Connection established dblinkCreated: File {0} has been created checkout: - toCreateBranch: To create new branch - branchName: Branch name - commitName: Commit name - updatedFromIndex: Updated {0} path{1} from the index + do: Do checkout... + toCreateBranch: "To create new branch: {0}" + branchName: "Branch name: {0}" + commitName: "Commit name: {0}" + commitMessage: "Commit message: {0}" + updatedFromIndex: Updated {0} path {1} from the index + printBranchAndCommit: "{0} ({1}) {2}" clone: cloned: Repository cloned commit: @@ -28,12 +35,12 @@ general: removed: Remote removed unknown: Unknown command init: - created: Repository created + created: Repository created dump: checking: Checking files... dumping: Dumping... - hash: hash - dbHash: db hash + hash: "hash: {0}" + dbHash: "db hash {0}" hashesDifferent: Hashes are different, saving to file... hashesMatch: Hashes match, no need to dump object... processing: Processing {0} @@ -44,28 +51,38 @@ general: fetch: fetching: Fetching... restore: + do: Do restore... scriptWillSaveTo: Script will be saved to {0} seekingToRemove: Seeking objects to remove... seekingToRestore: Seeking objects to restore... + seekingToRestoreAdditional: Seeking additional dependant objects to restore... toRestore: "Objects to restore:" + toRestoreAdditional: "Additional to restore:" toRemove: "Objects to remove:" notExists: Object {0} not exists in db, it will be removed from index + objectToRemove: Object {0} marked to delete nothingToRemove: No objects to remove nothingToRestore: No objects to restore + nothingToRestoreAdditional: No additional objects to restore restoring: Restoring... removing: Removing... removingObject: Removing {0}... created: Created file {0} + restoreType: Restoring {0} {1} ... restoreView: Restoring view {0} ... 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} ... restoreUser: Restoring user {0} ... restoreFnc: Restoring function {0} ... restoreTable: Restoring table {0} ... + restoreTableConstraints: Restoring table {0} constraints ... restoreTableData: Restoring table data for {0} ... restoreTablespace: Restoring tablespace {0} ... restoreConstr: Restoring constraints for table {0} ... @@ -75,14 +92,18 @@ general: addColumns: Adding columns... modifyColumns: Modifying columns... droppingColumns: Dropping columns... + droppingTablesConstraints: Dropping constraints for all updating tables... + droppingTableConstraints: Dropping constraints for table {0}... + restoringTablesConstraints: Restoring constraints for all updated tables... addPk: Adding PK... inserting: Inserting... deleting: Deleting... updating: Updating... unsupportedTypes: Table {0} contains unsupported types, it will be skipped willMakeBackup: Backup option enabled, all objects will be backed up before making changes + wontMakeBackup: Backup option DISABLED, no objects will be backed up before making changes toMakeChanges: Restore key specified, the operation will make changes to database - notMakeChanges: The operation will NOT make changes to database, a sql script was generated at {0}. Use "-r" key to make changes. + notMakeChanges: The operation will NOT make changes to database rm: checking: Checking files deleting: Deleting @@ -91,6 +112,14 @@ general: removingFromIndex: Removing from index... removingFromDb: Removing from db... markingToDelete: Marking item as removing in index + push: + noCommitsFound: No commits found! + remoteName: "remoteName: {0}" + called: Push called... + nullResult: Push result is null! + callResult: "Push call result: {0}" + result: "Push result: {0}" + upToDate: Everything up-to-date status: repVersion: "Repository version: {0}" dbgitVersion: "Dbgit version: {0}" @@ -113,11 +142,32 @@ general: diffSize1: MetaTableData diff size!!! {0} {1} diffSize2: MetaTableData diff size row {0}!!! diffDataRow: MetaTableData diff data row {0} {1} {2} {3} + loadRow: loading row {0} + loadedRow: loaded {0} rows + loadFiles: Loading files... + loadFile: Loading file {0}... backup: tryingToCopy: Trying to copy {0} to {1}... creatingSchema: Creating schema {0} droppingBackup: Dropping backup object {0}... + tryToBackup: Try to backup {0} present of {1} restoring objects ... + dependingBackups: Found {0} depending backups - {1} + rewritingBackups: Dropping {0} backups with {1} found dependencies... + creatingBackups: Creating {0} backups... + dbAdapter: + connectionLost: Connection lost, trying to reconnect... + reconnectTrySuccess: Successful reconnect. + reconnectTry: Try {0}... + convert: + processingTable: Converting table {0}... + convertingIndex: Converting table index {0} from {1} to {2} + convertingConstraint: Converting table constraint {0} from {1} to {2} + convertingField: Converting table field {0} from {1} to {2} + convertingSchema: Converting schema {0}... + convertingView: Converting view {0}... errors: + cmdException: "Error execute dbgit: {0}" + onExceptionTransactionRollbackError: "Failed to rollback connection: {0}" commandNotFound: Command {0} not found! executionError: Error execute dbgit gitRepNotFound: Git repository not found @@ -135,13 +185,15 @@ errors: fileLoadError: Error load file {0} errorParseIndex: Error parse ItemIndex! errorDump: Error write dump file + unsatisfiedDependencies: "There were objects with unsatisfied dependencies, they will NOT be included in restore list:" + metaTypeError: "The restore adapter encountered wrong MetaObject {0} type: expected {1}, got {2}" hash: errorSha: error search MessageDigest SHA-256 nullParam: Calc hash use null params unsupportedEncode: UnsupportedEncodingException UTF-8 link: emptyLink: Url database is empty - cantConnect: Test connection error + cantConnect: "Test connection error: {0}" restore: restoreErrorDidNotReturnTrue: Error restore objects.... restoreMetaObject must return true if object restore restoreError: Restore objects error @@ -153,6 +205,9 @@ errors: pkNotFound: PK not found for table {0}, cannot process row! cantConnect: Can't connect to db! errorLoadDelete: Error load and delete object + fileAlreadyExists: Error write script, file {0} already exists + 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! cantFindObjectInDb: Can't find object {0} in database @@ -184,15 +239,23 @@ errors: encrypted: Could not get ddl of database object {0}, the restoration is impossible tooManyRecords: Table {0} has more than {1} records. dbgit can't save this table data. compareMetaError: compareMeta Error! {0} to {1} + loadMetaFile: Could not load meta file {0}, using dummy version instead! + cantLoadMetaFile: Could not load meta file {0} dataTable: errorCellData: Error create CellData for type {0} differentCount: Different count columns title and line fieldNotFound: Field {0} not found + filesNotFound: Cound not find .data files in directories '{0}', put NULL values instead + tryAgain: Making attempt {0} getting portion of data... + wait: Error while getting portion of data, waiting {0} seconds before next try... + errorTableData: There was error while getting table data, error flag was ({0}) adapter: schemes: Error load schemes! tables: Error load tables! tableFields: Error load table fields! tableData: Error load table data! + tableSpace: Error load tablespace! + sequence: Error load sequence! index: Error load indexes! constraint: Error load constraints! views: Error load views! @@ -205,10 +268,17 @@ errors: roles: Error load roles! rollback: Error while rollback! createSchema: Cannot create schema + nullSchema: Object {0} has no schema set! + objectNotFoundInDb: Object is not found in target database! backup: badCommand: Bad command. Object to backup doesn't specified! backupError: Error on backup {0} cannotCreateSchema: Cannot create schema {0} + convert: + cannotConvert: Cannot convert {0}! + cannotFindAdapter: Could not get convert adapter for {0} ({1} version {2} -> {3} version {4}) + pull: + emptyGitRepository: Repo is empty! help: h: Shows this help v: Outputs full log of command execution @@ -248,6 +318,7 @@ help: Example: dbgit link jdbc:oracle:thin:@:: user= password= link-d: Creates default dblink file + link-ls: Just see current db url backup: | Examples: dbgit backup / -d -s @@ -260,12 +331,18 @@ help: dbgit add /TEST_VIEW.vw add-c: Let you continue adding from last place if it was broken checkout: | + Calls git checkout and 'dbgit restore' then Example: - dbgit checkout master + dbgit checkout master # checkout and restore (only script generated) + dbgit checkout master -r # checkout and restore with changing database + dbgit checkout master -nodb # checkout only + dbgit checkout -ls # see current branch checkout-b: create and checkout a new branch checkout-r: Updates database checkout-u: Upgrades branch to actual db and dbgit version state + checkout-ls: Just see current branch, head and revision number checkout-no-db: Doesn't do restore after checkout + checkout-no-owner: Doesn't restore objects original owner clone: | Example: dbgit clone @@ -335,4 +412,4 @@ help: config: | Example: dbgit config LIMIT_FETCH=true - config-g: sets global parameter \ No newline at end of file + config-g: sets global parameter diff --git a/src/main/resources/lang/rus.yaml b/src/main/resources/lang/rus.yaml index 02191c1..f675906 100644 --- a/src/main/resources/lang/rus.yaml +++ b/src/main/resources/lang/rus.yaml @@ -79,4 +79,4 @@ help: -h Показывает эту помощь -v Выводит полный отчет выполнения команды - \ No newline at end of file + diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 4ba1a99..143b89d 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -33,7 +33,7 @@ - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + %d{HH:mm} %level [%file:%line] : %msg%n @@ -43,7 +43,7 @@ - --> + diff --git a/src/test/java/ru/fusionsoft/dbgit/DBGitTest.java b/src/test/java/ru/fusionsoft/dbgit/DBGitTest.java new file mode 100644 index 0000000..9af0eac --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/DBGitTest.java @@ -0,0 +1,594 @@ +package ru.fusionsoft.dbgit; + +import com.diogonunes.jcdp.color.api.Ansi; +import com.google.common.collect.MapDifference; +import com.google.common.collect.Maps; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.apache.commons.io.FileUtils; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; +import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.RefSpec; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + +import ru.fusionsoft.dbgit.adapters.AdapterFactory; +import ru.fusionsoft.dbgit.adapters.IDBAdapter; +import ru.fusionsoft.dbgit.command.*; +import ru.fusionsoft.dbgit.core.*; +import ru.fusionsoft.dbgit.meta.IMapMetaObject; +import ru.fusionsoft.dbgit.meta.IMetaObject; +import ru.fusionsoft.dbgit.utils.ConsoleWriter; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import java.text.MessageFormat; +import java.util.*; + + +@Tag("deprecated") +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class DBGitTest { + + static Path RESOURCES_REPO_DIR = new File("src/test/resources/repo").toPath(); + static Path RECOURCES_REPO_GIT_DIR = RESOURCES_REPO_DIR.resolve(".git"); + + static String REPO_URL = "https://github.com/rocket-3/dbgit-test.git"; + static String REPO_BRANCH = "master"; + static List REPO_COMMIT_NUMBERS = new ArrayList<>(); + + static String TEST_DB_URL = "jdbc:postgresql://localhost/"; + static String TEST_DB_USER = "postgres"; + static String TEST_DB_PASS = ""; + static String TEST_DB_CATALOG = "test#databasegit"; + static boolean TO_CREATE_CATALOG = true; + static int messageLevel = 0; + + private static void addCatalogToUrl() { + TEST_DB_URL = MessageFormat.format( + "{0}{1}{2}", + TEST_DB_URL, + TEST_DB_URL.endsWith("/") ? "" : "/", + TEST_DB_CATALOG + ); + } + + @BeforeAll + public static void setUp() throws Exception { + printMethodHead("Set up", null); + ConsoleWriter.setDetailedLog(true); + + FileUtils.cleanDirectory(RESOURCES_REPO_DIR.toFile()); + DBGit.initUrlInstance(RECOURCES_REPO_GIT_DIR.toString(), false); + dbgitClone(REPO_URL, String.valueOf(RESOURCES_REPO_DIR)); + + configureTestDb(TO_CREATE_CATALOG); + + if(REPO_COMMIT_NUMBERS.isEmpty()){ + loadCommitNumbersFromRepo(); + } + + } + + @BeforeEach + public void setUpEach() throws Exception { +// printMethodHead("Before each", null); + configureDBConnection(); + } + + @Test + public void CmdLink() throws Exception { + printMethodHead("CmdLink", null); + + CmdLink cmd = new CmdLink(); + String notValidUrl = "jdbc:postgresql://4.4.4.4/"; + File dblinkFile = RESOURCES_REPO_DIR.resolve(".dbgit").resolve(".dblink").toFile(); + dblinkFile.delete(); + +// DriverManager.setLoginTimeout(3); +// cmd.execute(getLinkCommandLine(notValidUrl, null, null)); +// assertFalse(dblinkFile.exists(), "'.dblink file not created on non-valid url'"); + + cmd.execute(getLinkCommandLine(TEST_DB_URL, TEST_DB_USER, TEST_DB_PASS)); + assertTrue(dblinkFile.exists()); + + } + + @Test + public void CmdCheckout() throws Exception { + + printMethodHead("CmdCheckout", "init"); + boolean isNoDb = true ; + boolean isRestore = false; + boolean isCreateBranch = false; + boolean isUpgrade = false; + boolean isNoOwner = true; + + String scriptPath = RESOURCES_REPO_DIR.resolve("checkout-r.sql").toAbsolutePath().toString(); + File scriptFile = new File(scriptPath); + scriptFile.delete(); + GitMetaDataManager.getInstance().loadDBMetaData(); + + printMethodHead("CmdCheckout", "just checkout to first commit (-nodb)"); + dbgitCheckout(REPO_BRANCH, REPO_COMMIT_NUMBERS.get(0), isNoDb, isRestore, isCreateBranch, isUpgrade, isNoOwner); + + printMethodHead("CmdCheckout", "try with restore to first commit (-r)"); + dbgitCheckout(REPO_BRANCH, REPO_COMMIT_NUMBERS.get(0), false, true, isCreateBranch, isUpgrade, isNoOwner); + + printMethodHead("CmdCheckout", "try with restore to last commit (-s ...)" ); + assertDoesNotThrow( () -> + dbgitCheckout( + REPO_BRANCH, REPO_COMMIT_NUMBERS.get(REPO_COMMIT_NUMBERS.size() - 1), scriptPath, + false, false, isCreateBranch, isUpgrade, !TO_CREATE_CATALOG + ) + ); + assertTrue(scriptFile.exists()); + assertTrue(FileUtils.readFileToString(scriptFile).length() > 100); + } + + @Test + public void CmdRestore() throws Exception { + + boolean isRestore = false; + boolean isToMakeBackup = true; + boolean isNoDb = true; + boolean isCreateBranch = false; + boolean isUpgrade = false; + + + dbgitReset("hard"); + setToMakeBackup(isToMakeBackup); + + for(String commitNumber : REPO_COMMIT_NUMBERS){ + printMethodHead("CmdRestore", String.valueOf(REPO_COMMIT_NUMBERS.indexOf(commitNumber)) ); + + String scriptPath = RESOURCES_REPO_DIR.resolve(MessageFormat.format( + "restore#{0}.sql", + REPO_COMMIT_NUMBERS.indexOf(commitNumber) + )).toAbsolutePath().toString(); + String scriptPathA = scriptPath+"-again"; + File scriptFile = new File(scriptPath); + File scriptFileA = new File(scriptPathA); + + scriptFile.delete(); + + dbgitCheckout(REPO_BRANCH, commitNumber, scriptPath, isNoDb, isRestore, isCreateBranch, isUpgrade, !TO_CREATE_CATALOG); + ConsoleWriter.printlnGreen(MessageFormat.format( + "\tIndex of commit in list: [{0}]", REPO_COMMIT_NUMBERS.indexOf(commitNumber) + ), messageLevel + ); + + + scriptFile.delete(); + dbgitRestore(true, true, scriptPath); + scriptFileA.delete(); + dbgitRestore(false, true, scriptPathA); + + + ConsoleWriter.printLineBreak(); + //TODO assert sizes have no difference + ConsoleWriter.printlnGreen(MessageFormat.format( + "File 1st: {0} syms.\nFile 2nd: {1} syms.", + scriptFile.exists() ? FileUtils.readFileToString(scriptFile).length() : -1, + scriptFileA.exists() ? FileUtils.readFileToString(scriptFileA).length() :- 1 + ), messageLevel); + } + } + + @Test + public void CmdAdd() throws Exception { + printMethodHead("CmdAdd", null); + + CmdAdd cmd = new CmdAdd(); + // checkout to last commit - restore files and database + // checkout 1st commit - restore files, index + // call cmdAdd + // ensure files added (what files?) - from last commit db state + + String firstCommit = REPO_COMMIT_NUMBERS.get(0); + String lastCommit = REPO_COMMIT_NUMBERS.get(REPO_COMMIT_NUMBERS.size()-1); + + dbgitCheckout(REPO_BRANCH, lastCommit, false, true, false, false, false); + dbgitCheckout(REPO_BRANCH, firstCommit, true, false, false, false, false); + + IMapMetaObject fileImos = GitMetaDataManager.getInstance().loadFileMetaData(); + IMapMetaObject databaseImos = GitMetaDataManager.getInstance().loadDBMetaData(); + + + ConsoleWriter.detailsPrintln("Find file to db object difference: ", messageLevel); + MapDifference diffs = Maps.difference(fileImos, databaseImos); + + diffs.entriesDiffering().forEach( (metaKey, metaObject) -> { + ConsoleWriter.detailsPrintlnGreen(metaKey, messageLevel+1); + + Map fileImoMap = metaObject.leftValue().toMap(); + Map dbImoMap = metaObject.rightValue().toMap(); + printMapsDifference(dbImoMap, fileImoMap, messageLevel+1); + + }); + + } + + //TODO вынести в отдельный метод с параметрами + //@Test + public void CmdClone() throws Exception { + printMethodHead("CmdClone", null); + + FileUtils.cleanDirectory(RESOURCES_REPO_DIR.toFile()); + //TODO кстати, вот он + dbgitClone(REPO_URL, String.valueOf(RESOURCES_REPO_DIR)); + configureDBConnection(); + + + File gitFile = RESOURCES_REPO_DIR.resolve(".git").toFile(); + File dbgitFile = RESOURCES_REPO_DIR.resolve(".dbgit").toFile(); + File[] dbgitFiles = dbgitFile.listFiles(); + + assertTrue(gitFile.exists(), "'.git folder exists'"); + assertTrue(dbgitFile.exists(), "'.dbgit folder exists'"); + assertTrue(dbgitFiles != null && dbgitFiles.length > 0, "'.dbgit folder is not empty'"); + + ConsoleWriter.printlnGreen(MessageFormat.format("Number of files in .dbgit {0}", dbgitFiles.length ), messageLevel); + Arrays.asList(dbgitFiles).forEach(x->ConsoleWriter.printlnRed(x.getPath(), messageLevel+1)); + + } + + //@Test + public void CmdReset() throws Exception { + printMethodHead("CmdReset", null); + + dbgitCheckout(REPO_BRANCH, REPO_COMMIT_NUMBERS.get(0), true, false, false, false, false); + + File dblinkFile = RESOURCES_REPO_DIR.resolve(".dbgit").resolve(".dblink").toFile(); + List modes = Arrays.asList("soft", "mixed", "hard", "merge", "keep"); + + dblinkFile.delete(); + assertFalse(dblinkFile.exists()); + + dbgitReset("hard"); + assertTrue(dblinkFile.exists()); + + } + + private static void dbgitClone(String urlFrom, String dirTo) throws Exception { + CmdClone cmdClone = new CmdClone(); + StringBuilder sb = new StringBuilder(); + + Option directoryOption = Option.builder().longOpt("directory").hasArg(true).numberOfArgs(1).build(); + directoryOption.getValuesList().add(dirTo); + + CommandLine cmdLineClone = new CommandLine.Builder() + .addArg(urlFrom) + .addOption(directoryOption).build(); + + sb.append(urlFrom + " "); + sb.append("-directory " + dirTo); + + ConsoleWriter.printlnGreen(MessageFormat.format("(call) dbgit {0} {1}", "clone", sb.toString()), messageLevel); + + cmdClone.execute(cmdLineClone); + } + + private static void dbgitReset(String mode) throws Exception { + StringBuilder sb = new StringBuilder(); + sb.append(mode); + + CmdReset cmd = new CmdReset(); + Option optionMode = new Option(mode , false, mode); + CommandLine.Builder builder = new CommandLine.Builder(); + ConsoleWriter.println(MessageFormat.format("(call) dbgit {0} {1}", "reset", sb.toString()), messageLevel); + + cmd.execute(builder.addOption(optionMode).build()); + } + + private static void dbgitCheckout(String branchName, String commitNumber, + boolean isNoDb, boolean isRestore, boolean isCreateBranch, + boolean isUpgrade, boolean isNoOwner) throws Exception { + dbgitCheckout(branchName, commitNumber, null, + isNoDb, isRestore, isCreateBranch, + isUpgrade, isNoOwner + ); + } + private static void dbgitCheckout(String branchName, String commitNumber, String scriptPath, + boolean isNoDb, boolean isRestore, boolean isCreateBranch, + boolean isUpgrade, boolean isNoOwner + ) throws Exception { + CmdCheckout cmd = new CmdCheckout(); + CommandLine.Builder builder = new CommandLine.Builder(); + StringBuilder sb = new StringBuilder(); + + String actualBranchName = branchName == null ? "master" : branchName; + + Option nodbOption = Option.builder("nodb").hasArg(false).build(); + Option noOwnerOption = Option.builder("noowner").hasArg(false).build(); + Option restoreOption = Option.builder("r").hasArg(false).build(); + Option newBranchOption = Option.builder("b").hasArg(false).build(); + Option upgradeOption = Option.builder("u").hasArg(false).build(); + Option scriptOption = Option.builder("s").hasArg(true).build(); + + builder.addArg(actualBranchName); + if(commitNumber != null){ + builder.addArg(commitNumber); + sb.append(commitNumber + " "); + } + if(isNoDb){ + builder.addOption(nodbOption); + sb.append("-nodb "); + } + if(isRestore){ + builder.addOption(restoreOption); + sb.append("-r "); + } + if(isCreateBranch){ + builder.addOption(newBranchOption); + sb.append("-b "); + } + if(isUpgrade){ + builder.addOption(upgradeOption); + sb.append("-u "); + } + if(isNoOwner){ + builder.addOption(noOwnerOption); + sb.append("-noowner "); + + } + if(scriptPath != null){ + scriptOption.getValuesList().add(scriptPath); + builder.addOption(scriptOption); + sb.append("-s ").append(scriptPath).append(" "); + } + builder.addOption(Option.builder("v").hasArg(false).build()); + ConsoleWriter.println(MessageFormat.format("(call) dbgit {0} {1}", "checkout", sb.toString()), messageLevel); + + + cmd.execute(builder.build()); + } + + private static void dbgitCheckoutLs() throws Exception { + CmdCheckout cmd = new CmdCheckout(); + CommandLine.Builder builder = new CommandLine.Builder(); + + Option lsOption = Option.builder("ls").hasArg(false).build(); + builder.addOption(lsOption); + + ConsoleWriter.println(MessageFormat.format("(call) dbgit {0}", "checkout -ls"), messageLevel); + cmd.execute(builder.build()); + } + + private static void dbgitRestore(boolean isRestore, boolean isToMakeBackup, String scriptPath) throws Exception { + + CmdRestore cmd = new CmdRestore(); + CommandLine.Builder builder = new CommandLine.Builder(); + StringBuilder sb = new StringBuilder(); + + builder.addOption(Option.builder("v").hasArg(false).build()); + sb.append("-v "); + + if(isRestore){ + Option restoreOption = Option.builder("r").hasArg(false).build(); + builder.addOption(restoreOption); + sb.append("-r "); + } + if(!TO_CREATE_CATALOG){ + Option noownerOption = Option.builder("noowner").hasArg(false).build(); + builder.addOption(noownerOption); + sb.append("-noowner "); + } + if(scriptPath != null){ + Option scriptOption = Option.builder("s").hasArg(true).numberOfArgs(1).build(); + scriptOption.getValuesList().add(scriptPath); + builder.addOption(scriptOption); + sb.append("-s ").append(scriptPath); + } + + ConsoleWriter.println(MessageFormat.format("(call) dbgit {0} {1}", "checkout", sb.toString()), messageLevel); + setToMakeBackup(isToMakeBackup); + cmd.execute(builder.build()); + } + + private static void configureTestDb(boolean tryCreateCatalog) throws Exception { + Properties testDbProps = new Properties(); + + String propDbUrl = System.getProperty("pgTestDbUrl"); + String propDbUser = System.getProperty("pgTestDbUser"); + String propDbPass = System.getProperty("pgTestDbPass"); + + ConsoleWriter.println("(config) Using test database: ", messageLevel); + if(propDbUrl != null){ + ConsoleWriter.print(" "); + TEST_DB_URL = propDbUrl; + TEST_DB_USER = propDbUser; + TEST_DB_PASS = propDbPass; + } else { + ConsoleWriter.print(" "); + } + ConsoleWriter.print(TEST_DB_URL); + + if(TEST_DB_USER != null && TEST_DB_PASS != null){ + testDbProps.put("user", TEST_DB_USER); + testDbProps.put("password", TEST_DB_PASS); + } + + if(tryCreateCatalog){ + try (Connection conn = DriverManager.getConnection(TEST_DB_URL, testDbProps)) { + + if (!conn.getCatalog().isEmpty()) { + throw new Exception("Catalog must not be specified to create test catalog."); + } + + IDBAdapter adapter = AdapterFactory.createAdapter(conn); + + try(Statement stmt = conn.createStatement()){ + stmt.execute(MessageFormat.format( + "DROP DATABASE \"{0}\"'; ", + adapter.escapeNameIfNeeded(TEST_DB_CATALOG) + )); + } catch (Exception ex){ + ConsoleWriter.println( + "(config) failed to drop database: " + ex.getMessage().replaceAll("\n", ";") + , messageLevel + ); + } + + try(Statement stmt = conn.createStatement()){ + stmt.execute(MessageFormat.format( + "CREATE DATABASE \"{0}\"; ", + adapter.escapeNameIfNeeded(TEST_DB_CATALOG) + )); + } catch (Exception ex){ + ConsoleWriter.println( + "(config) failed to create database: " + ex.getMessage().replaceAll("\n", ";") + , messageLevel + ); + //throw ex; + } + + } + } + addCatalogToUrl(); + + + DBConnection.createFileDBLink(TEST_DB_URL, testDbProps, false); + + } + + private static void configureDBConnection() throws Exception { + String dbLinkUrl = DBConnection.loadFileDBLink(new Properties()); + + if( !DBConnection.hasInstance() || + !DBConnection.getInstance().getConnect().getMetaData().getURL().equals(TEST_DB_URL)){ + + new CmdLink().execute(getLinkCommandLine(TEST_DB_URL, TEST_DB_USER, TEST_DB_PASS)); + if(DBConnection.hasInstance()) { + DBConnection.getInstance().flushConnection(); + DBConnection.getInstance(); + } + + ConsoleWriter.printlnGreen(MessageFormat.format( + "(config) Set up DBConnection and ''.dblink'' state, \n\twas\t: {0} \n\tset\t: {1}" + , dbLinkUrl + , DBConnection.getInstance().getConnect().getMetaData().getURL() + ), messageLevel); + } + + //not to broke any other database + assertEquals(TEST_DB_URL, DBConnection.getInstance().getConnect().getMetaData().getURL(), "DBConnection url IS NOT equal to test database url" ); + } + + private static void loadCommitNumbersFromRepo() throws GitAPIException, IOException { + InMemoryRepository repo = new InMemoryRepository(new DfsRepositoryDescription()); + Git git = new Git(repo); + git.fetch() + .setRemote(REPO_URL) + .setRefSpecs(new RefSpec("+refs/heads/"+ REPO_BRANCH +":refs/heads/"+ REPO_BRANCH)) + .call(); + + String treeName = "refs/heads/"+ REPO_BRANCH; // tag or branch + for (RevCommit commit : git.log().add(repo.resolve(treeName)).call()) { + REPO_COMMIT_NUMBERS.add(commit.getName()); + } + } + + private static void setToMakeBackup(boolean isToMakeBackup) throws Exception { + String sectionName = "core"; + String parameterName = "TO_MAKE_BACKUP"; + String was = String.valueOf(DBGitConfig.getInstance().getBoolean(sectionName, parameterName, false)); + + DBGitConfig.getInstance().setValue("TO_MAKE_BACKUP", isToMakeBackup ? "true" : "false"); + + ConsoleWriter.detailsPrintlnRed(MessageFormat.format("(config) Set ''TO_MAKE_BACKUP'' (was, set, now): {0}, {1}, {2}", + was, String.valueOf(isToMakeBackup), + String.valueOf(DBGitConfig.getInstance().getBoolean(sectionName, parameterName, false)) + ), messageLevel); + } + + private static CommandLine getLinkCommandLine(String url, String user, String pass){ + CommandLine.Builder builder = new CommandLine.Builder().addArg(url); + if(user != null) { + builder.addArg("user=" + user); + + } + if(pass != null) { + builder.addArg("password=" + pass); + } + return builder.build(); + } + + private static void printMethodHead(String name, String part){ + String text = name + ((part != null) ? " part '" + part + "'" : "") ; + int length = 92; + int textLength = text.length(); + boolean shouldAddSpace = textLength % 2 != length % 2; + int remSpaceLength = length - textLength - (shouldAddSpace ? 0 : 1); + int sideHeaderLength = remSpaceLength / 2; + StringBuilder sb = new StringBuilder(); + + for ( int step = 0; step < 2; step ++){ + if( step == 0 ) sb.append(text); + for (int i = sideHeaderLength; i > 0;){ + sb.append(" -"); i -= 2; + if( i == 2 ) { sb.append(" "); i--; } + if( i == 1 ) { sb.append("|\n") ; i--; } + } + + sb.reverse(); + } + + ConsoleWriter.printlnColor(sb.toString(), Ansi.FColor.MAGENTA, 0); + } + + private static void printMapsDifference(Map mapBefore, Map mapAfter, int level){ + + MapDifference difference = Maps.difference(mapBefore, mapAfter); + Map add = difference.entriesOnlyOnRight(); + Map remove = difference.entriesOnlyOnLeft(); + Map> change = difference.entriesDiffering(); + + for (Map.Entry addEntry : add.entrySet()) { + ConsoleWriter.println(MessageFormat.format("+ ''{0}'': ", addEntry.getKey()), level); + printNode( addEntry.getValue(), level ); + } + + for (Map.Entry removeEntry : remove.entrySet()) { + ConsoleWriter.println(MessageFormat.format("- ''{0}'': ", removeEntry.getKey()), level); + //printNode( removeEntry.getValue(), level ); + } + + for (Map.Entry> changeEntry : change.entrySet()) { + ConsoleWriter.println(MessageFormat.format("* ''{0}'': ", changeEntry.getKey()), level); + + Object valueBefore = changeEntry.getValue().leftValue(); + Object valueAfter = changeEntry.getValue().rightValue(); + + if( valueBefore instanceof Map && valueAfter instanceof Map ){ + printMapsDifference((Map) valueBefore, (Map) valueAfter, level+1); + } else { + ConsoleWriter.print(MessageFormat.format("\"{0}\" -> \"{1}\"", valueBefore, valueAfter)); + } + + } + } + + private static void printNode(Object node, int level){ + if(node instanceof Map) { + Map map = (Map) node; + + for (Map.Entry entry : map.entrySet()) { + ConsoleWriter.println(MessageFormat.format("''{0}'': " ,entry.getKey()), level+1); + printNode( entry.getValue(), level+1); + } + } + else { + ConsoleWriter.print(node != null ? node : ""); + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/MetaObjectTest.java b/src/test/java/ru/fusionsoft/dbgit/MetaObjectTest.java deleted file mode 100644 index 9251afd..0000000 --- a/src/test/java/ru/fusionsoft/dbgit/MetaObjectTest.java +++ /dev/null @@ -1,135 +0,0 @@ -package ru.fusionsoft.dbgit; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -//import junit.framework.TestCase; -import ru.fusionsoft.dbgit.dbobjects.DBConstraint; -import ru.fusionsoft.dbgit.dbobjects.DBIndex; -import ru.fusionsoft.dbgit.dbobjects.DBSchema; -import ru.fusionsoft.dbgit.dbobjects.DBTable; -import ru.fusionsoft.dbgit.dbobjects.DBTableField; -import ru.fusionsoft.dbgit.meta.DBGitMetaType; -import ru.fusionsoft.dbgit.meta.MetaObjOptions; -import ru.fusionsoft.dbgit.meta.MetaObjectFactory; -import ru.fusionsoft.dbgit.meta.MetaSchema; -import ru.fusionsoft.dbgit.meta.MetaTable; -import ru.fusionsoft.dbgit.utils.StringProperties; - -public class MetaObjectTest /*extends TestCase*/ { - public final String targetPath = "target"; - - /* - public void testMetaTable() { - DBTable tbl = new DBTable(); - - tbl.setName("mytable"); - tbl.setSchema("myschema"); - tbl.getOptions().addChild("owner", "postgres"); - tbl.getOptions().addChild("table_space", "pg_default"); - StringProperties sub = (StringProperties)tbl.getOptions().addChild("sub"); - sub.addChild("sub1", "val1"); - sub.addChild("sub2", "val2"); - - MetaTable tblMeta = new MetaTable(tbl); - - DBTableField field = new DBTableField(); - field.setName("id"); - field.setTypeSQL("integer"); - field.setIsPrimaryKey(true); - tblMeta.getFields().put(field.getName(), field); - - field = new DBTableField(); - field.setName("field1"); - field.setTypeSQL("character varying(255)"); - field.setIsPrimaryKey(false); - tblMeta.getFields().put(field.getName(), field); - - field = new DBTableField(); - field.setName("field2"); - field.setTypeSQL("timestamp without time zone"); - tblMeta.getFields().put(field.getName(), field); - - field = new DBTableField(); - field.setName("field3"); - field.setTypeSQL("integer"); - tblMeta.getFields().put(field.getName(), field); - - DBIndex idx = new DBIndex(); - idx.setName("idx1"); - idx.setSchema("myschema"); - idx.setSql("CREATE INDEX idx1 ON crtd.notice USING btree (depart);"); - tblMeta.getIndexes().put(idx.getName(), idx); - - idx = new DBIndex(); - idx.setName("idx2"); - idx.setSchema("myschema"); - idx.setSql("CREATE INDEX idx2 ON crtd.notice USING btree (depart);"); - tblMeta.getIndexes().put(idx.getName(), idx); - - DBConstraint ct = new DBConstraint(); - ct.setName("fk1"); - ct.setSchema("myschema"); - ct.setSql("ALTER TABLE crtd.notice ADD CONSTRAINT fk1 FOREIGN KEY (arrive) REFERENCES crtd.ptstation (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION;"); - tblMeta.getConstraints().put(ct.getName(), ct); - - ct = new DBConstraint(); - ct.setName("fk2"); - ct.setSchema("myschema"); - ct.setSql("ALTER TABLE crtd.notice ADD CONSTRAINT fk2 FOREIGN KEY (arrive) REFERENCES crtd.ptstation (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION;"); - tblMeta.getConstraints().put(ct.getName(), ct); - - try { - String filename = targetPath+"/test.yaml"; - FileOutputStream out = new FileOutputStream(filename); - tblMeta.serialize(out); - out.close(); - - - File file = new File(filename); - FileInputStream fis = new FileInputStream(file); - MetaTable meta2 = (MetaTable)tblMeta.deSerialize(fis); - fis.close(); - - assertEquals("Assert meta name!", "myschema/mytable.tbl", meta2.getName()); - assertEquals("Assert meta name!", "mytable", meta2.getTable().getName()); - assertEquals("Assert meta name!", "val1", meta2.getTable().getOptions().xPath("sub/sub1").getData()); - - assertEquals("Assert meta hash!", tblMeta.getHash(), meta2.getHash()); - //assertEquals("Assert meta hash!", tblMeta.getHash(), "hash"); - - - } catch (Exception e) { - e.printStackTrace(); - assertTrue(e.getMessage(), false ); - } - } - - */ - - public void testMetaShema() throws Exception { - DBSchema sh = new DBSchema("myshema"); - StringProperties pr = sh.getOptions(); - pr.setData("info value"); - pr.addChild("param1", "val1"); - pr.addChild("param2", "val2"); - pr.addChild("param3", "val3"); - - StringProperties sub = pr.addChild("subparams"); - sub.addChild("subparam1", "asd1"); - sub.addChild("subparam2", "asd2"); - - MetaObjOptions meta = (MetaObjOptions)MetaObjectFactory.createMetaObject(DBGitMetaType.DBGitSchema); - meta.setObjectOption(sh); - - //assertEquals("Assert hash!", meta.getHash(), "5c376e1836f4cbc763808fe077a84f2eaf9cdb9dc7e22107fc44a9567f4cf264"); - - /* - System.out.println(meta.getHash()); - - System.out.println(pr.toString()); - */ - //TODO to yaml and assert - } -} diff --git a/src/test/java/ru/fusionsoft/dbgit/UtilTest.java b/src/test/java/ru/fusionsoft/dbgit/UtilTest.java deleted file mode 100644 index 3f8cf80..0000000 --- a/src/test/java/ru/fusionsoft/dbgit/UtilTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package ru.fusionsoft.dbgit; - -import com.jcraft.jsch.jce.Random; -/* -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -*/ -import ru.fusionsoft.dbgit.dbobjects.DBTableField; - -import ru.fusionsoft.dbgit.utils.MaskFilter; - -public class UtilTest /*extends TestCase*/ { - public void testMask() { - /* - MaskFilter mask = new MaskFilter("asd*.txt"); - assertTrue(mask.match("asd12df.txt")); - assertFalse(mask.match("as612df.txt")); - - mask = new MaskFilter("path/asd*.txt"); - assertTrue(mask.match("path/asd12df.txt")); - assertFalse(mask.match("as612df.txt")); - - mask = new MaskFilter("path/*"); - assertTrue(mask.match("path/asd12df.txt")); - assertFalse(mask.match("pat/as612df.txt")); - - mask = new MaskFilter("path/w*"); - assertTrue(mask.match("path\\wsd12df.txt")); - assertFalse(mask.match("pat\\ws612df.txt")); - */ - } - - public void testMapField() { - /* - IMapFields map = new TreeMapFields(); - - DBTableField f1 = new DBTableField(); - f1.setName("f1"); - DBTableField f2 = new DBTableField(); - f2.setName("f2"); - DBTableField f3 = new DBTableField(); - f3.setName("f3"); - DBTableField f4 = new DBTableField(); - f4.setName("f4"); - - - for (int i = 0; i < 10000; i++) { - DBTableField f = new DBTableField(); - f.setName("item_"+Math.random()*10000000); - map.put(f); - } - - - map.put(f2); - map.put(f1); - map.put(f3); - map.put(f4); - */ - - - } -} diff --git a/src/test/java/ru/fusionsoft/dbgit/core/DBGitIgnoreTest.java b/src/test/java/ru/fusionsoft/dbgit/core/DBGitIgnoreTest.java new file mode 100644 index 0000000..f842ad2 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/core/DBGitIgnoreTest.java @@ -0,0 +1,33 @@ +package ru.fusionsoft.dbgit.core; + +import ru.fusionsoft.dbgit.utils.MaskFilter; + +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + +public class DBGitIgnoreTest { + + DBGitIgnore dbGitIgnore; + Map filters = new HashMap<>(); + Map exclusions = new HashMap<>(); + + private void createDbGitIgnore(){ + dbGitIgnore = new DBGitIgnore(filters, exclusions); + } + + private void addFilter(String mask){ filters.put(mask, new MaskFilter(mask)); } + private void addExcl(String mask){ exclusions.put(mask, new MaskFilter(mask)); } + + + + @Test + public void matchOne() { + createDbGitIgnore(); + addExcl("public/*.*"); + + final String textTbl = "public/ad_group_roles.tbl"; + assertFalse(dbGitIgnore.matchOne(textTbl)); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestBasic.java b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestBasic.java new file mode 100644 index 0000000..fdffffe --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestBasic.java @@ -0,0 +1,361 @@ +package ru.fusionsoft.dbgit.integration; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import ru.fusionsoft.dbgit.integration.primitives.Patch; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitCheckout; +import ru.fusionsoft.dbgit.integration.primitives.DescribedTestResult; +import ru.fusionsoft.dbgit.integration.primitives.GroupedTestResult; +import ru.fusionsoft.dbgit.integration.primitives.SimpleTest; +import ru.fusionsoft.dbgit.integration.primitives.SimpleTestResult; +import ru.fusionsoft.dbgit.integration.primitives.TestResult; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitLinkPgAuto; +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; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit.CharsDbIgnoreWithTableData; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.NameOfDefaultTargetTestDatabase; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.UrlOfGitTestRepo; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchCreatingFile; +import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitAdd; +import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitInitializesRepo; +import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitLink; +import ru.fusionsoft.dbgit.integration.primitives.path.PathPatched; +import ru.fusionsoft.dbgit.integration.primitives.path.PathWithFiles; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.scenarios.PathAfterDbGitLinkAndAdd; +import ru.fusionsoft.dbgit.integration.primitives.path.PathAfterDbGitRun; +import ru.fusionsoft.dbgit.integration.primitives.path.PathNotProjectRoot; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.PathWithDbGitRepoCloned; +import ru.fusionsoft.dbgit.integration.primitives.path.PathWithoutFiles; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.ProjectTestResourcesCleanDirectoryPath; + +@Tag("integration") +public class DbGitIntegrationTestBasic { + + @Test + public final void doesNothingIntegrationTestTemplate() { + final String description = "Does nothing test works"; + final TestResult result = + new GroupedTestResult<>( + description, + new PathPatched( + new ProjectTestResourcesCleanDirectoryPath("00"), + new Patch() { + @Override + public void apply(Path root) throws Exception { + + } + } + ), + new SimpleTest<>( + "Returns true", + (path) -> { + path.toString(); + return true; + } + ) + ); + + System.out.println(result.text()); + Assertions.assertTrue(result.value()); + } + + @Test + public final void gitToFilesCheckoutWorks() { + final String description = "Dbgit checkout and reset works"; + final String branchName = "dsdata"; + final String commitNameOfHead = "9e91d86"; + final String commitNameOfDs2 = "83baf51"; + final String fileName = ".dbgit/.dblink"; + final String reamdeFileName = "README.md"; + final String expectedFileContent = "ds2"; + final TestResult testResult = new GroupedTestResult<>( + description, + + new PathAfterDbGitRun( + new ArgsDbGitCheckout(commitNameOfDs2, "-nodb", "-v"), + + new PathAfterDbGitRun( + new ArgsDbGitCheckout(branchName, "-b", "-nodb", "-v"), + + new PathAfterDbGitRun( + new ArgsDbGitAddRemoteTestRepo("origin"), + + new PathWithDbGitRepoCloned( + new UrlOfGitTestRepo(), + new ProjectTestResourcesCleanDirectoryPath("01") + ) + ) + ) + ), + new SimpleTest<>( + "Printed expected commit hash", + (path) -> { + final CharSequence consoleOutput = new CharsOfConsoleWhenRunning(() -> { + new PathAfterDbGitRun(new ArgsExplicit("checkout", "-ls", "-v"), path).toString(); + }); + System.out.println(consoleOutput); + return new LinesOfUnsafeScalar(consoleOutput) + .list() + .stream() + .anyMatch(x -> x.contains(commitNameOfDs2)); + } + ), + new SimpleTest<>( + "File content of "+fileName+" is as expected", + (path) -> { + return Files.readAllLines(path.resolve(fileName)) + .stream() + .anyMatch(x->x.contains(expectedFileContent)); + } + ), + new SimpleTest<>( + "File "+reamdeFileName+" does not exists", + (path) -> { + return ! path.resolve("README.md").toFile().exists(); + } + ), + new SimpleTest<>( + "File "+reamdeFileName+" exists after checkout back to ", + (path) -> { + return new PathPatched( + new PatchSequential( + new PathPatchDbGitCheckout(branchName, "-nodb", "-v"), + new PathPatchDbGitCheckout("-ls", "-v") + ), + path + ).resolve(reamdeFileName).toFile().exists(); + } + ) + ); + + System.out.println(testResult.text()); + Assertions.assertTrue(testResult.value()); + } + + @Test + public final void dbToFilesDumpWorks() { + final String description = "Dbgit add with table data works"; + final TestResult result = new GroupedTestResult( + description, + + new PathAfterDbGitRun( + new ArgsExplicit("add", "\"*\""), + + new PathWithFiles( + new PathPatchCreatingFile(".dbgit/.dbignore", new CharsDbIgnoreWithDataAndTypes()), + + new PathAfterDbGitRun( + new ArgsDbGitLinkPgAuto("dvdrental"), + + new PathAfterDbGitRun( + new ArgsExplicit("init"), + + new ProjectTestResourcesCleanDirectoryPath("02") + ) + ) + ) + ), + + new SimpleTest<>( + "git folder exists", + (path) -> { + return path.resolve(".git").toFile().exists(); + } + ), + new SimpleTest<>( + "rental table data exists", + (path) -> { + return path.resolve(".dbgit/public/rental.csv").toFile().exists(); + } + ), + new SimpleTest<>( + "city table data (small) is not empty", + (path) -> { + return ! Files.readAllLines(path.resolve(".dbgit/public/city.csv")).isEmpty(); + } + ), + new SimpleTest<>( + "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 path.resolve(".dbgit/public/film_summary.udt").toFile().exists(); + } + ) + ); + + System.out.println(result.text()); + Assertions.assertTrue(result.value()); + } + + @Test + public final void dbToDbRestoreWorks() { + final String nameOfSourceDb = "dsd3"; + final String nameOfTargetDb = new NameOfDefaultTargetTestDatabase().toString(); + final String description = + "Simple add from '" + nameOfSourceDb + "' db with data " + + "and restore to '" + nameOfTargetDb + "' db works"; + + final TestResult result = new GroupedTestResult<>( + description, + new PathPatched( + new PatchSequential( + new PathPatchDbGitInitializesRepo(new ArgsDbGitLinkPgAuto(nameOfSourceDb)), + new PathPatchCreatingFile(".dbgit/.dbignore", new CharsDbIgnoreWithTableData()), + new PathPatchDbGitAdd(), + new PathPatchDbGitLink(new ArgsDbGitLinkPgAuto(nameOfTargetDb)), + new PathPatchDbGitRestore("-r", "-v") + ), + new ProjectTestResourcesCleanDirectoryPath("03") + ), + new SimpleTest<>( + "Should not throw any exceptions", + (path) -> { + path.toString(); + return true; + } + ) + ); + + System.out.println(result.text()); + Assertions.assertTrue(result.value()); + } + + @Test + public final void gitToDbRestoreWorks() throws Exception { + + final String nameOfSourceBranch = "dsdata"; + final String description = + "Simple sequential checkout from '" + nameOfSourceBranch + "' branch " + + "and restore to '" + new NameOfDefaultTargetTestDatabase() + "' db works"; + + final List commitNames = new CommitsFromRepo( + new UrlOfGitTestRepo().toString(), nameOfSourceBranch + ).names(); + + final ArgsDbGitLinkPgAuto linkArgs = new ArgsDbGitLinkPgAuto(new NameOfDefaultTargetTestDatabase()); + final TestResult result = new GroupedTestResult<>( + description, + new PathPatched( + new PatchSequential( + new PathPatchDbGitClonesRepo(new UrlOfGitTestRepo(), new ArgsDbGitAddRemoteTestRepo()), + 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 PathPatchDbGitCheckoutHard(commitNames.get(1), "-nodb", "-v"), + new PathPatchDbGitLink(linkArgs), + new PathPatchCreatingFile(".dbgit/dbgitconfig", new CharsDbGitConfigBackupEnabled()), + new PathPatchDbGitRestore("-r", "-v"), + new PathPatchDbGitCheckoutHard(commitNames.get(2), "-nodb", "-v"), + new PathPatchDbGitLink(linkArgs), + new PathPatchCreatingFile(".dbgit/dbgitconfig", new CharsDbGitConfigBackupEnabled()), + new PathPatchDbGitRestore("-r", "-v") + ), + new ProjectTestResourcesCleanDirectoryPath("04") + ), + new SimpleTest<>( + "Should not throw any exceptions", + (path) -> { + path.toString(); + return true; + } + ) + ); + + System.out.println(result.text()); + Assertions.assertTrue(result.value()); + } + + @Test + public final void dbToDbRestoreWorksWithCustomTypes() { + final String description = "Hardest sakilla_database sequential add and restore with table data and custom types (mpaa_rating) works"; + final TestResult result = new DescribedTestResult( + description, + new SimpleTestResult<>( + new PathAfterDbGitRun( + //pagilla to test#databasegit over dvdrental + new ArgsExplicit("restore", "-r", "-v"), + + new PathAfterDbGitRun( + new ArgsDbGitLinkPgAuto(new NameOfDefaultTargetTestDatabase()), + + //pagilla to local repo + new PathAfterDbGitLinkAndAdd( + new ArgsDbGitLinkPgAuto("pagilla"), + new CharsDbIgnoreWithDataAndTypes(), + + //dvdrental to test#databasegit + new PathAfterDbGitRun( + new ArgsExplicit("restore", "-r", "-v"), + + new PathAfterDbGitRun( + new ArgsDbGitLinkPgAuto(new NameOfDefaultTargetTestDatabase()), + + //dvdrental to local repo + new PathAfterDbGitLinkAndAdd( + new ArgsDbGitLinkPgAuto("dvdrental"), + new CharsDbIgnoreWithDataAndTypes(), + + new PathAfterDbGitRun( + new ArgsExplicit("init"), + + new PathWithoutFiles( + "*", + new PathNotProjectRoot( + new ProjectTestResourcesCleanDirectoryPath("05") + ) + ) + ) + ) + ) + ) + ) + ) + ), + new SimpleTest<>( + "Should not throw any exceptions", + (path) -> { + path.toString(); + return true; + } + ) + ) + ); + + System.out.println(result.text()); + Assertions.assertTrue(result.value()); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestExtendedCommands.java b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestExtendedCommands.java new file mode 100644 index 0000000..8124cfc --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestExtendedCommands.java @@ -0,0 +1,7 @@ +package ru.fusionsoft.dbgit.integration; + +import org.junit.jupiter.api.Tag; + +@Tag("integration") +public class DbGitIntegrationTestExtendedCommands { +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestNotebook.java b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestNotebook.java new file mode 100644 index 0000000..218bebc --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/DbGitIntegrationTestNotebook.java @@ -0,0 +1,148 @@ +package ru.fusionsoft.dbgit.integration; + +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; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitLinkPgAuto; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchCreatingFile; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningGit; +import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchGitCheckoutOrphan; +import ru.fusionsoft.dbgit.integration.primitives.path.PathAfterDbGitRun; +import ru.fusionsoft.dbgit.integration.primitives.path.PathAfterGitRun; +import ru.fusionsoft.dbgit.integration.primitives.path.PathPatched; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.scenarios.PathAfterDbGitLinkAndAdd; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.PathWithDbGitRepoCloned; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.DescribedTestResult; +import ru.fusionsoft.dbgit.integration.primitives.SimpleTest; +import ru.fusionsoft.dbgit.integration.primitives.SimpleTestResult; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitAddRemoteTestRepo; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitLinkPgLocal; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit.CharsDbIgnoreWithTableData; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.UrlOfGitTestRepo; +import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitCheckout; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.ProjectTestResourcesCleanDirectoryPath; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.scenarios.PathAfterDbGitDumpsDbSchemaToGit; + +@Tag("notebook") +@Disabled +public class DbGitIntegrationTestNotebook { + @Test + public final void appendsDbSchemaToBranchOfTestRepo() { + final String description = "Appends db schema to existing git branch"; + final String nameOfBranchToAppendTo = "sakilla-data"; + final String nameOfDbToDump = "dvdrental"; + final String nameOfRemote = "origin-test"; + final CharSequence ignoreChars = new CharsDbIgnoreWithTableData(); + final DescribedTestResult result = new DescribedTestResult<>( + description, + new SimpleTestResult<>( + new PathAfterDbGitDumpsDbSchemaToGit( + nameOfDbToDump, + nameOfRemote, + new UrlOfGitTestRepo(), + new ArgsDbGitLinkPgLocal(nameOfDbToDump), + new ArgsDbGitAddRemoteTestRepo(nameOfRemote), + ignoreChars, + new PathPatchDbGitCheckout( + nameOfBranchToAppendTo, + "-b", + "-nodb", + "-v" + ), + new DefaultPrintStream(), + new ProjectTestResourcesCleanDirectoryPath(description) + ), + new SimpleTest<>( + (path) -> { + return path.resolve(".dbgit/public/rental.csv").toFile().exists(); + } + ) + ) + ); + + System.out.println("\n" + result.text()); + Assertions.assertTrue(result.value()); + } + + @Test + public final void dumpsDbSchemaToNewBranchOfTestRepo() { + final String nameOfNewBranch = "sakilla-data"; + final String nameOfDbToDump = "pagilla"; + final String nameOfRemote = "origin-test"; + final String description = "Dumps db schema to new git branch"; + final CharSequence ignoreChars = new CharsDbIgnoreWithTableData(); + + new PathAfterGitRun( + new ArgsExplicit("push", nameOfRemote, nameOfNewBranch, "-v"), + + new PathAfterDbGitRun( + new ArgsExplicit("commit", "-m", nameOfDbToDump), + + new PathAfterDbGitLinkAndAdd( + new ArgsDbGitLinkPgAuto(nameOfDbToDump), + ignoreChars, + + new PathPatched( + new PathPatchGitCheckoutOrphan(nameOfNewBranch), + + new PathAfterDbGitRun( + new ArgsDbGitAddRemoteTestRepo(nameOfRemote), + + new PathWithDbGitRepoCloned( + new UrlOfGitTestRepo(), + + new ProjectTestResourcesCleanDirectoryPath( + description + ) + ) + ) + ) + ) + ) + ).toString(); + + } + + @Test + public final void cleansBranch() { + final String branchToClean = "master"; + final String nameOfNewBranch = "orphan"; + final String nameOfRemote = "origin"; + final String description = "Replaces branch " + + branchToClean + + " with a new git branch"; + + new PathPatched( + new PatchSequential<>( + new PathPatchGitCheckoutOrphan(nameOfNewBranch), + new PathPatchCreatingFile("readme.md", "Just a clean branch"), + new PathPatchRunningGit("add", "readme.md"), + new PathPatchRunningGit("commit", "-m", "\"clean branch\""), + new PathPatchRunningGit("push", nameOfRemote, + MessageFormat.format( + "+{0}:{1}", nameOfNewBranch, branchToClean + ) + ) + ), + new PathAfterDbGitRun( + new ArgsDbGitAddRemoteTestRepo(nameOfRemote), + + new PathWithDbGitRepoCloned( + new UrlOfGitTestRepo(), + new ProjectTestResourcesCleanDirectoryPath( + description + ) + ) + ) + + ).toString(); + + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/SelfTest.java b/src/test/java/ru/fusionsoft/dbgit/integration/SelfTest.java new file mode 100644 index 0000000..73eacc6 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/SelfTest.java @@ -0,0 +1,206 @@ +package ru.fusionsoft.dbgit.integration; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import ru.fusionsoft.dbgit.integration.primitives.TestResult; +import ru.fusionsoft.dbgit.integration.primitives.files.AutoDeletingTempFilePath; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchCreatingFile; +import ru.fusionsoft.dbgit.integration.primitives.path.PathNotProjectRoot; +import ru.fusionsoft.dbgit.integration.primitives.path.PathPatched; +import ru.fusionsoft.dbgit.integration.primitives.path.PathPrintsToConsole; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.CurrentWorkingDirectory; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.ProjectTestResourcesCleanDirectoryPath; +import ru.fusionsoft.dbgit.integration.primitives.DescribedTestResult; +import ru.fusionsoft.dbgit.integration.primitives.GroupedTestResult; +import ru.fusionsoft.dbgit.integration.primitives.Patch; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; +import ru.fusionsoft.dbgit.integration.primitives.SimpleTest; +import ru.fusionsoft.dbgit.integration.primitives.SimpleTestResult; + +public class SelfTest { + + @Test + public final void subjectSideEffectAppearsOnceWhenAccessingTwice() throws Exception { + Assertions.assertEquals( + 2, + new DescribedTestResult( + "Test result subject side effect appears once", + new SimpleTestResult( + new PathPrintsToConsole( + "Line printed as side effect...", + new ProjectTestResourcesCleanDirectoryPath( + "Test result subject side effect appears once" + ) + ), + new SimpleTest<>(subj -> { + subj.isAbsolute(); + subj.toString(); + subj.toFile(); + return true; + }) + ) + ) + .text() + .split("\n") + .length + ); + } + + @Test + public final void failsToFalseOnException() { + final ProjectTestResourcesCleanDirectoryPath workingDirectory = + new ProjectTestResourcesCleanDirectoryPath( + "Fails to false on exception"); + + Assertions.assertDoesNotThrow( + () -> { + final TestResult testResult = + new DescribedTestResult( + "Fails to false on exception", + new SimpleTestResult( + new PathPatched( + new PathNotProjectRoot(workingDirectory), + new Patch() { + @Override + public void apply(Path root) throws Exception { + System.out.println("access " + root.toString()); + throw new RuntimeException("dummy error"); + } + } + ), + new SimpleTest<>(path -> { + path.toString(); + path.toString(); + path.toString(); + path.toString(); + return ! path + .resolve("pom.xml") + .toFile() + .exists(); + }) + ) + ); + + Assertions.assertFalse(testResult.value()); + } + ); + } + + @Test + public final void groupedTestResultWorks() { + final TestResult result = new GroupedTestResult( + "Grouped test result works", + new ProjectTestResourcesCleanDirectoryPath( + "Grouped test result works" + ), + new SimpleTest( + "Retruns true", + (path) -> { + path.toString(); + return true; + } + ), + new SimpleTest<>( + "Throws exception", + (path) -> { + path.toString(); + throw new Exception("dummy expection"); + } + ), + new SimpleTest<>( + "Throws error", + (path) -> { + path.toString(); + throw new Error("dummy error the second"); + } + ) + ); + Assertions.assertFalse(result.value()); + } + + @Test + public final void patchedWorks() { + final ProjectTestResourcesCleanDirectoryPath workingDirectory = + new ProjectTestResourcesCleanDirectoryPath( + "Patched works" + ); + + final String fileName = "testFile.txt"; + final String content = "content"; + + final TestResult result = new GroupedTestResult<>( + "Patched works", + new PathPatched( + new PathNotProjectRoot(workingDirectory), + new PathPatchCreatingFile(fileName, content) + ), + + new SimpleTest<>( + "File exists", + path -> { + return path.resolve(fileName).toFile().exists(); + } + ), + new SimpleTest<>( + "File content as expected", + path -> { + return FileUtils.readFileToString( + path.resolve(fileName).toFile() + ) + .contains(content); + } + ) + ); + + System.out.println(result.text()); + Assertions.assertTrue(result.value()); + } + + @Test + public final void patchSequentalWorks() { + final String fileName = "abc.txt"; + final String fileContent = "cba"; + final DescribedTestResult result = new DescribedTestResult( + "Sequental patch works", + new SimpleTestResult<>( + new PathPatched( + new PathNotProjectRoot( + new ProjectTestResourcesCleanDirectoryPath( + "Sequental patch works" + ) + ), + new PatchSequential<>( + new PathPatchCreatingFile(fileName, "abc"), + new PathPatchCreatingFile(fileName, fileContent) + ) + ), + new SimpleTest<>( + "File content is as expected", + x -> FileUtils.readFileToString(x.resolve(fileName).toFile()) + .equals(fileContent) + + ) + ) + ); + + System.out.println(result.text()); + Assertions.assertTrue(result.value()); + + } + + @Test + public final void tempFileWorks() throws IOException { + Path path = new CurrentWorkingDirectory(); + try (AutoDeletingTempFilePath tempFilePath = new AutoDeletingTempFilePath(new CurrentWorkingDirectory(), "some")) { + path = tempFilePath; + final String data = "123"; + FileUtils.writeStringToFile(tempFilePath.toFile(), data); + Files.readAllLines(tempFilePath.toFile().toPath()).contains(data); + } + Assertions.assertFalse(path.toFile().exists()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/StickyFunctionTest.java b/src/test/java/ru/fusionsoft/dbgit/integration/StickyFunctionTest.java new file mode 100644 index 0000000..caf5371 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/StickyFunctionTest.java @@ -0,0 +1,31 @@ +package ru.fusionsoft.dbgit.integration; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import ru.fusionsoft.dbgit.integration.primitives.Function; +import ru.fusionsoft.dbgit.integration.primitives.StickyFunction; + +import java.util.concurrent.atomic.AtomicInteger; + +public class StickyFunctionTest { + + @Test + public void returnsValue() throws Exception { + Assertions.assertEquals( + 4, + new StickyFunction( (x) -> x+2 ).value(2) + ); + } + + @Test + public void returnsSameValue() throws Exception { + final AtomicInteger accessCount = new AtomicInteger(0); + final Function sticky = new StickyFunction<>( + (x) -> accessCount.incrementAndGet() + ); + Assertions.assertEquals( + sticky.value(0), + sticky.value(0) + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/PathAfterDbGitMainRun.java b/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/PathAfterDbGitMainRun.java new file mode 100644 index 0000000..97d3d6a --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/PathAfterDbGitMainRun.java @@ -0,0 +1,35 @@ +package ru.fusionsoft.dbgit.integration.deprecated; + +import java.nio.file.Path; +import java.util.Arrays; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.path.PathEnvelope; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.CurrentWorkingDirectory; + +public class PathAfterDbGitMainRun extends PathEnvelope { + public PathAfterDbGitMainRun(Args args, Path origin) { + super(() -> { + final boolean originIsNotAppWorkingDirectory = ( + ! new CurrentWorkingDirectory() + .toAbsolutePath() + .toString() + .equals(origin.toAbsolutePath().toString()) + ); + if ( originIsNotAppWorkingDirectory ) { + throw new RuntimeException( + "Given path:" + + "\n->" + origin.toAbsolutePath().toString() + + "\nis not an App's working directory:" + + "\n->" + new CurrentWorkingDirectory().toAbsolutePath().toString() + + "\nSo App cant apply to the given Path" + ); + } + origin.toString(); + System.out.println("\n> dbgit " + String.join( + " ", + Arrays.asList(args.values()) + )); + return new WithDbGitMainRunScalar<>(args, origin).value(); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/PathAfterExecutableRun.java b/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/PathAfterExecutableRun.java new file mode 100644 index 0000000..3950d14 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/PathAfterExecutableRun.java @@ -0,0 +1,88 @@ +package ru.fusionsoft.dbgit.integration.deprecated; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithPrepend; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOf; +import ru.fusionsoft.dbgit.integration.primitives.path.PathAfterProcessRun; +import ru.fusionsoft.dbgit.integration.primitives.path.PathEnvelope; + +public class PathAfterExecutableRun extends PathEnvelope { + public PathAfterExecutableRun( + Args commandInterface, + CharSequence executableName, + Args command, + PrintStream printStream, + Path origin + ) { + super( + () -> + new PathAfterProcessRun( + new ArgsWithPrepend( + new ArgsWithPrepend( + command, + executableName + ), + commandInterface + ), + printStream, + origin + ) + ); + } + + public PathAfterExecutableRun( + Args commandInterface, + CharSequence executableName, + Args executableArgs, + Path workingDirectory + ) { + this( + commandInterface, + executableName, + executableArgs, + new DefaultPrintStream(), + workingDirectory + ); + } + + public PathAfterExecutableRun( + CharSequence executableName, + Args args, + PrintStream printStream, + Path workingDirectory + ) { + this( + new ArgsExplicit(System.getenv("ComSpec"), "/C"), + executableName, + args, + printStream, + workingDirectory + ); + } + + public PathAfterExecutableRun( + CharSequence executableName, + Args args, + Path workingDirectory + ) { + this( + executableName, + args, + new DefaultPrintStream(), + workingDirectory + ); + } + + public PathAfterExecutableRun(Path executablePath, Args args, Path workingDirectory) { + this( + new CharsOf<>(Path::toString, executablePath), + args, + workingDirectory + ); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/SystemUserDirPath.java b/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/SystemUserDirPath.java new file mode 100644 index 0000000..75dc48b --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/SystemUserDirPath.java @@ -0,0 +1,10 @@ +package ru.fusionsoft.dbgit.integration.deprecated; + +import java.nio.file.Paths; +import ru.fusionsoft.dbgit.integration.primitives.path.PathEnvelope; + +public class SystemUserDirPath extends PathEnvelope { + public SystemUserDirPath(){ + super(()->Paths.get(System.getProperty("user.dir"))); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/WithDbGitMainRunScalar.java b/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/WithDbGitMainRunScalar.java new file mode 100644 index 0000000..b65fc19 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/deprecated/WithDbGitMainRunScalar.java @@ -0,0 +1,26 @@ +package ru.fusionsoft.dbgit.integration.deprecated; + +import java.util.Arrays; +import ru.fusionsoft.dbgit.App; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; + +public class WithDbGitMainRunScalar implements Scalar { + private final Args args; + private final Y origin; + + public WithDbGitMainRunScalar(Args args, Y origin) { + this.args = args; + this.origin = origin; + } + + @Override + public final Y value() throws Exception { + App.main( + Arrays.stream(this.args.values()) + .map(String::valueOf) + .toArray(String[]::new) + ); + return origin; + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Args.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Args.java new file mode 100644 index 0000000..a6b95e6 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Args.java @@ -0,0 +1,5 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public interface Args { + CharSequence[] values(); +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Credentials.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Credentials.java new file mode 100644 index 0000000..08e0b4d --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Credentials.java @@ -0,0 +1,6 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public interface Credentials { + String username() ; + String password() ; +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/DescribedTestResult.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/DescribedTestResult.java new file mode 100644 index 0000000..a99af00 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/DescribedTestResult.java @@ -0,0 +1,44 @@ +package ru.fusionsoft.dbgit.integration.primitives; +import java.text.MessageFormat; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsQuotedToRegexPattern; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.test.LabelOfTestRunResult; + +public class DescribedTestResult implements TestResult { + private final String description; + private final TestResult testResult; + + public DescribedTestResult(String description, TestResult testResult) { + this.description = description; + this.testResult = testResult; + } + + public DescribedTestResult(String description, Subj subject, Test test) { + this(description, new SimpleTestResult<>(subject, test)); + } + + @Override + public final boolean value() { + return this.testResult.value(); + } + + @Override + public final String text() { + final CharSequence valueChars = new CharsQuotedToRegexPattern( + new LabelOfTestRunResult(this.testResult.value()) + ); + + return this.testResult + .text() + .replaceFirst( + String.valueOf(valueChars), + MessageFormat.format( + "{0} {1}", + valueChars, + this.description + ) + + ); + + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Function.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Function.java new file mode 100644 index 0000000..232e585 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Function.java @@ -0,0 +1,6 @@ +package ru.fusionsoft.dbgit.integration.primitives; + + +public interface Function{ + Y value(X source) throws Exception; +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/GroupedTestResult.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/GroupedTestResult.java new file mode 100644 index 0000000..19467e8 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/GroupedTestResult.java @@ -0,0 +1,26 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.test.LabelOfTestRunResult; +import ru.fusionsoft.dbgit.integration.primitives.chars.LinesOfString; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.test.ReportOfTestGroupRun; + +public class GroupedTestResult implements TestResult { + private final CharSequence text; + + @SafeVarargs + public GroupedTestResult(CharSequence description, Subj subject, Test... tests ) { + this.text = new ReportOfTestGroupRun<>(description, subject, tests); + } + + @Override + public final boolean value() { + return String.valueOf( + new LinesOfString(String.valueOf(this.text)).list().get(0) + ).contains(new LabelOfTestRunResult(true)); + } + + @Override + public final String text() { + return String.valueOf(this.text); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Patch.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Patch.java new file mode 100644 index 0000000..c5685e4 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Patch.java @@ -0,0 +1,8 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +/* + A consumer, but can throw checked + */ +public interface Patch { + void apply(T root) throws Exception; +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/PatchSequential.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/PatchSequential.java new file mode 100644 index 0000000..6fd4353 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/PatchSequential.java @@ -0,0 +1,24 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +import java.util.Arrays; +import java.util.Collection; + +public class PatchSequential implements Patch { + private final Collection> patches; + + public PatchSequential(final Collection> patches) { + this.patches = patches; + } + + @SafeVarargs + public PatchSequential(final Patch... patches) { + this(Arrays.asList(patches)); + } + + @Override + public final void apply(final T root) throws Exception { + for (final Patch patch : patches) { + patch.apply(root); + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/PatchedScalar.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/PatchedScalar.java new file mode 100644 index 0000000..9e5ab58 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/PatchedScalar.java @@ -0,0 +1,17 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public class PatchedScalar implements Scalar { + private final T origin; + private final Patch patch; + + public PatchedScalar(T origin, Patch patch) { + this.origin = origin; + this.patch = patch; + } + + @Override + public final T value() throws Exception { + this.patch.apply(origin); + return origin; + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/RunnableWithException.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/RunnableWithException.java new file mode 100644 index 0000000..c5b7358 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/RunnableWithException.java @@ -0,0 +1,5 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public interface RunnableWithException { + void run() throws Exception; +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SafeScalar.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SafeScalar.java new file mode 100644 index 0000000..f4c756b --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SafeScalar.java @@ -0,0 +1,5 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public interface SafeScalar { + T value(); +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SafeScalarOf.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SafeScalarOf.java new file mode 100644 index 0000000..82eb6bb --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SafeScalarOf.java @@ -0,0 +1,28 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public class SafeScalarOf implements SafeScalar { + private final Scalar origin; + + public SafeScalarOf(Scalar origin) { + this.origin = origin; + } + + public SafeScalarOf(Function origin, X value){ + this( () -> origin.value(value) ) ; + } + + @Override + public final Y value() { + try { + return origin.value(); + } catch (Exception e) { + throw new SafeScalarError(e); + } + } + + public static class SafeScalarError extends Error { + public SafeScalarError(Throwable cause) { + super("Error occurs while constructing safe scalar value", cause); + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Scalar.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Scalar.java new file mode 100644 index 0000000..cc822de --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Scalar.java @@ -0,0 +1,8 @@ +package ru.fusionsoft.dbgit.integration.primitives; + + +public interface Scalar { + T value() throws Exception; + + Scalar DONT_CARE = () -> { throw new Exception("Not implemented"); }; +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SimpleTest.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SimpleTest.java new file mode 100644 index 0000000..93d0bf2 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SimpleTest.java @@ -0,0 +1,26 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public class SimpleTest implements Test { + private final Function predicate; + private final String description; + + public SimpleTest(String description, Function predicate) { + this.description = description; + this.predicate = predicate; + } + + public SimpleTest(Function predicate) { + this.description = "test just runs without errors"; + this.predicate = predicate; + } + + @Override + public final boolean value(Subj subj) throws Exception { + return this.predicate.value(subj); + } + + @Override + public final String description() { + return this.description; + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SimpleTestResult.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SimpleTestResult.java new file mode 100644 index 0000000..0285828 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/SimpleTestResult.java @@ -0,0 +1,23 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.test.LabelOfTestRunResult; +import ru.fusionsoft.dbgit.integration.primitives.chars.specific.test.ReportOfTestRun; + +public class SimpleTestResult implements TestResult { + private final CharSequence text; + public SimpleTestResult(Subj subject, Test test) { + this.text = new ReportOfTestRun<>(subject, test); + } + + @Override + public final String text() { + return String.valueOf(this.text); + } + + @Override + public final boolean value() { + return this + .text() + .contains(String.valueOf(new LabelOfTestRunResult(true))); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/StickyFunction.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/StickyFunction.java new file mode 100644 index 0000000..73a181c --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/StickyFunction.java @@ -0,0 +1,32 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +import java.util.HashMap; +import java.util.Map; + +public class StickyFunction implements Function { + private final Function origin; + private final Map cachedValues; + + private StickyFunction(Function origin, Map cachedValues) { + this.origin = origin; + this.cachedValues = cachedValues; + } + + public StickyFunction(Function origin){ + this(origin, new HashMap<>()); + } + + public StickyFunction(Scalar origin){ + this((x) -> { + return origin.value(); + }); + } + + @Override + public Y value(X arg) throws Exception { + if (!cachedValues.containsKey(arg)) { + cachedValues.put(arg, origin.value(arg)); + } + return cachedValues.get(arg); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/StickyScalar.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/StickyScalar.java new file mode 100644 index 0000000..a79c5fe --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/StickyScalar.java @@ -0,0 +1,25 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public class StickyScalar implements Scalar { + private final Function origin; + + public StickyScalar(Scalar origin) { + this.origin = new StickyFunction<>(origin); + } + + public StickyScalar(Function origin, X value) { + this( + new Scalar() { + @Override + public Y value() throws Exception { + return origin.value(value); + } + } + ); + } + + @Override + public final Y value() throws Exception { + return this.origin.value(true); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Test.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Test.java new file mode 100644 index 0000000..8686e04 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/Test.java @@ -0,0 +1,6 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public interface Test { + String description(); + boolean value(Subj subj) throws Exception; +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/TestResult.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/TestResult.java new file mode 100644 index 0000000..1409c54 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/TestResult.java @@ -0,0 +1,6 @@ +package ru.fusionsoft.dbgit.integration.primitives; + +public interface TestResult { + String text(); + boolean value(); +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsExplicit.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsExplicit.java new file mode 100644 index 0000000..7559fe9 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsExplicit.java @@ -0,0 +1,13 @@ +package ru.fusionsoft.dbgit.integration.primitives.args; + +import ru.fusionsoft.dbgit.integration.primitives.Args; + +public class ArgsExplicit implements Args { + private final CharSequence[] args; + public ArgsExplicit(CharSequence... values) { + this.args = values.clone(); + } + public final CharSequence[] values() { + return this.args; + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsRunningCommand.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsRunningCommand.java new file mode 100644 index 0000000..09df2d2 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsRunningCommand.java @@ -0,0 +1,33 @@ +package ru.fusionsoft.dbgit.integration.primitives.args; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOf; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOfLines; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsWithBoundary; + +public class ArgsRunningCommand extends ArgsExplicit { + public ArgsRunningCommand(CharSequence commandName) { + super( + ( System.getenv("ComSpec") == null ) + ? new CharSequence[]{commandName} + : new CharSequence[]{System.getenv("ComSpec"), "/C", commandName} + ); + } + public ArgsRunningCommand(Args commandRunArgs) { + super( + ( System.getenv("ComSpec") == null ) + ? new CharSequence[]{"sh", "-c", new CharsWithBoundary(new CharsOfLines(commandRunArgs), "\"")} + : new CharSequence[]{System.getenv("ComSpec"), "/C", new CharsOfLines(commandRunArgs)} + ); + } + public ArgsRunningCommand(Path executablePath) { + this( + new CharsOf<>( + Object::toString, + executablePath + ) + ); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsWithAppend.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsWithAppend.java new file mode 100644 index 0000000..91964b0 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsWithAppend.java @@ -0,0 +1,27 @@ +package ru.fusionsoft.dbgit.integration.primitives.args; + +import org.apache.commons.lang3.ArrayUtils; +import ru.fusionsoft.dbgit.integration.primitives.Args; + +public class ArgsWithAppend implements Args { + private final Args origin; + private final Args append; + + public ArgsWithAppend(Args origin, Args append) { + this.origin = origin; + this.append = append; + } + + public ArgsWithAppend(Args origin, String... append) { + this.origin = origin; + this.append = new ArgsExplicit(append.clone()); + } + + @Override + public final CharSequence[] values() { + return ArrayUtils.addAll( + origin.values(), + append.values() + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsWithPrepend.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsWithPrepend.java new file mode 100644 index 0000000..b3f7b19 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/ArgsWithPrepend.java @@ -0,0 +1,26 @@ +package ru.fusionsoft.dbgit.integration.primitives.args; + +import org.apache.commons.lang3.ArrayUtils; +import ru.fusionsoft.dbgit.integration.primitives.Args; + +public class ArgsWithPrepend implements Args { + private final Args origin; + private final Args prepend; + + public ArgsWithPrepend(Args origin, Args prepend) { + this.origin = origin; + this.prepend = prepend; + } + public ArgsWithPrepend(Args origin, CharSequence... prepend) { + this.origin = origin; + this.prepend = new ArgsExplicit(prepend); + } + + @Override + public final CharSequence[] values() { + return ArrayUtils.addAll( + prepend.values(), + origin.values() + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAdd.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAdd.java new file mode 100644 index 0000000..f8d8def --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAdd.java @@ -0,0 +1,13 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithPrepend; + +public class ArgsDbGitAdd extends ArgsWithPrepend { + public ArgsDbGitAdd(CharSequence mask) { + super(new ArgsExplicit(mask), "add", "-v"); + } + public ArgsDbGitAdd() { + this("\"*\""); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAddRemote.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAddRemote.java new file mode 100644 index 0000000..0d8ffc4 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAddRemote.java @@ -0,0 +1,17 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; + +public class ArgsDbGitAddRemote extends ArgsExplicit { + public ArgsDbGitAddRemote(String url, String name, String user, String pass) { + super( + "remote", "add", name, + "https://" + + user + + ":" + + pass + + "@" + + url + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAddRemoteTestRepo.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAddRemoteTestRepo.java new file mode 100644 index 0000000..126f1e1 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitAddRemoteTestRepo.java @@ -0,0 +1,24 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.Credentials; +import ru.fusionsoft.dbgit.integration.primitives.credentials.specific.CredsOfGitTestRepo; + +public class ArgsDbGitAddRemoteTestRepo extends ArgsDbGitAddRemote { + public ArgsDbGitAddRemoteTestRepo(String url, String name, String user, String pass) { + super(url, name, user, pass); + } + public ArgsDbGitAddRemoteTestRepo(String url, String name, Credentials credentials) { + this(url, name, credentials.username(), credentials.password()); + } + public ArgsDbGitAddRemoteTestRepo(String name) { + this( + "github.com/rocket-3/dbgit-test.git", + name, + new CredsOfGitTestRepo() + ); + } + public ArgsDbGitAddRemoteTestRepo() { + this("origin"); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitCheckout.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitCheckout.java new file mode 100644 index 0000000..986cbbb --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitCheckout.java @@ -0,0 +1,16 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithAppend; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithPrepend; + +public class ArgsDbGitCheckout extends ArgsWithPrepend { + + public ArgsDbGitCheckout(CharSequence... args) { + super( + new ArgsExplicit(args), + "checkout" + ); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitClone.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitClone.java new file mode 100644 index 0000000..e642d97 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitClone.java @@ -0,0 +1,18 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOf; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.CurrentWorkingDirectory; + +public class ArgsDbGitClone extends ArgsExplicit { + public ArgsDbGitClone(CharSequence repoUrl, CharSequence directoryToCloneToChars) { + super("clone", repoUrl, "--directory", "\"" + directoryToCloneToChars + "\""); + } + public ArgsDbGitClone(CharSequence repoUrl, Path directoryToCloneTo) { + this(repoUrl, new CharsOf<>(()->directoryToCloneTo.toAbsolutePath().toString())); + } + public ArgsDbGitClone(CharSequence repoUrl) { + this(repoUrl, "."); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitInit.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitInit.java new file mode 100644 index 0000000..c3b76eb --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitInit.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; + +public class ArgsDbGitInit extends ArgsExplicit { + public ArgsDbGitInit() { + super("init"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLink.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLink.java new file mode 100644 index 0000000..596a4e8 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLink.java @@ -0,0 +1,31 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalar; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalarOf; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; +import ru.fusionsoft.dbgit.integration.primitives.StickyScalar; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; + +public class ArgsDbGitLink implements Args { + private final SafeScalar argsScalar; + + public ArgsDbGitLink(Scalar origin) { + this.argsScalar = new SafeScalarOf(new StickyScalar<>(origin)); + } + public ArgsDbGitLink(CharSequence url, CharSequence database, CharSequence user, CharSequence pass) { + this(()-> { + return new ArgsExplicit( + "link", + url + "/" + database, + "user=" + user, + "password=" + pass + ); + }); + } + @Override + public final CharSequence[] values() { + return argsScalar.value().values(); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgAuto.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgAuto.java new file mode 100644 index 0000000..afa53be --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgAuto.java @@ -0,0 +1,7 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +public class ArgsDbGitLinkPgAuto extends ArgsDbGitLink { + public ArgsDbGitLinkPgAuto(CharSequence databaseName) { + super(()->new ArgsDbGitLinkPgRemote(databaseName)); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgLocal.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgLocal.java new file mode 100644 index 0000000..6a701db --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgLocal.java @@ -0,0 +1,22 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.Credentials; +import ru.fusionsoft.dbgit.integration.primitives.credentials.specific.CredsOfPgTestDatabase; + +public class ArgsDbGitLinkPgLocal extends ArgsDbGitLink { + public ArgsDbGitLinkPgLocal(CharSequence database, CharSequence user, CharSequence pass) { + super( + "jdbc:postgresql://localhost", + database, + user, + pass + ); + + } + public ArgsDbGitLinkPgLocal(CharSequence database, Credentials credentials) { + this(database, credentials.username(), credentials.password()); + } + public ArgsDbGitLinkPgLocal(CharSequence database) { + this(database, new CredsOfPgTestDatabase()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgRemote.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgRemote.java new file mode 100644 index 0000000..9731bdf --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitLinkPgRemote.java @@ -0,0 +1,26 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.Credentials; +import ru.fusionsoft.dbgit.integration.primitives.credentials.specific.CredsOfPgTestDatabase; + +public class ArgsDbGitLinkPgRemote extends ArgsDbGitLink { + public ArgsDbGitLinkPgRemote(CharSequence database, CharSequence username, CharSequence password) { + super( + "jdbc:postgresql://135.181.94.98:31007", + database, + username, + password + ); + } + + public ArgsDbGitLinkPgRemote(CharSequence database, Credentials credentials) { + this(database, credentials.username(), credentials.password()); + } + + public ArgsDbGitLinkPgRemote(CharSequence database) { + this( + database, + new CredsOfPgTestDatabase() + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitReset.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitReset.java new file mode 100644 index 0000000..0c20019 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitReset.java @@ -0,0 +1,10 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithPrepend; + +public class ArgsDbGitReset extends ArgsWithPrepend { + public ArgsDbGitReset(CharSequence nameOfResetMode) { + super(new ArgsExplicit(nameOfResetMode), "reset"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitRestore.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitRestore.java new file mode 100644 index 0000000..edb3b57 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/args/specific/ArgsDbGitRestore.java @@ -0,0 +1,10 @@ +package ru.fusionsoft.dbgit.integration.primitives.args.specific; + +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithPrepend; + +public class ArgsDbGitRestore extends ArgsWithPrepend { + public ArgsDbGitRestore(CharSequence... restoreCommandArgs) { + super(new ArgsExplicit(restoreCommandArgs), "restore"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharSequenceEnvelope.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharSequenceEnvelope.java new file mode 100644 index 0000000..32db886 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharSequenceEnvelope.java @@ -0,0 +1,54 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.util.stream.IntStream; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; +import ru.fusionsoft.dbgit.integration.primitives.StickyScalar; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalar; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalarOf; + +public abstract class CharSequenceEnvelope implements CharSequence { + private final SafeScalar origin; + + private CharSequenceEnvelope(final SafeScalar origin) { + this.origin = origin; + } + + public CharSequenceEnvelope(final Scalar origin) { + this( + new SafeScalarOf<>( + new StickyScalar<>(origin) + ) + ); + } + + + @Override + public final int length() { + return origin.value().length(); + } + + @Override + public final char charAt(int i) { + return origin.value().charAt(i); + } + + @Override + public final CharSequence subSequence(int i, int i1) { + return origin.value().subSequence(i, i1); + } + + @Override + public final IntStream chars() { + return origin.value().chars(); + } + + @Override + public final IntStream codePoints() { + return origin.value().codePoints(); + } + + @Override + public final String toString() { + return origin.value().toString(); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOf.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOf.java new file mode 100644 index 0000000..20f20c1 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOf.java @@ -0,0 +1,15 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import ru.fusionsoft.dbgit.integration.primitives.Function; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; +import ru.fusionsoft.dbgit.integration.primitives.StickyScalar; + +public class CharsOf extends CharSequenceEnvelope { + public CharsOf(Function extraction, X source) { + super(new StickyScalar(extraction, source)); + } + + public CharsOf(Scalar scalar) { + super(new StickyScalar<>(scalar)); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfConsoleWhenRunning.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfConsoleWhenRunning.java new file mode 100644 index 0000000..ca3a7d2 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfConsoleWhenRunning.java @@ -0,0 +1,40 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.StringTokenizer; +import ru.fusionsoft.dbgit.integration.primitives.RunnableWithException; + +public class CharsOfConsoleWhenRunning extends CharsOf { + + public CharsOfConsoleWhenRunning(RunnableWithException runnable) { + super(() -> { + final PrintStream original = System.out; + try (final ByteArrayOutputStream cachedOutputStream = new ByteArrayOutputStream();) { + try { + System.setOut(new PrintStream(cachedOutputStream, true, "UTF-8")); + + runnable.run(); + return cachedOutputStream.toString(); + + } catch (Throwable e) { + throw new CharsOfConsoleWhenRunningException(cachedOutputStream, e); + } finally { + System.setOut(original); + } + } + }); + } + + public static class CharsOfConsoleWhenRunningException extends Error { + public CharsOfConsoleWhenRunningException(String text, Throwable cause) { + super( + (text.isEmpty() ? "Execution broken after:\n" : "") + text, + cause + ); + } + public CharsOfConsoleWhenRunningException(ByteArrayOutputStream byteArrayOutputStream, Throwable cause) { + this(byteArrayOutputStream.toString(), cause); + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfLines.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfLines.java new file mode 100644 index 0000000..1287880 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfLines.java @@ -0,0 +1,38 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalar; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalarOf; + +public class CharsOfLines extends CharSequenceEnvelope { + public CharsOfLines(SafeScalar> charsListScalar, CharSequence delimiterChars, CharSequence itemPrefixChars) { + super(() -> { + return charsListScalar + .value() + .stream() + .map(x -> String.valueOf(itemPrefixChars) + x) + .collect(Collectors.joining(delimiterChars)); + } + ); + } + public CharsOfLines(Lines lines, CharSequence delimiterChars, CharSequence itemPrefixChars) { + this( new SafeScalarOf<>(lines::list), delimiterChars, itemPrefixChars ); + } + public CharsOfLines(List list, CharSequence delimiterChars, CharSequence itemPrefixChars) { + this( new SafeScalarOf<>(()->list), delimiterChars, itemPrefixChars); + } + public CharsOfLines(Args args, CharSequence delimiterChars, CharSequence itemPrefixChars) { + this( new SafeScalarOf<>(()-> Arrays.asList(args.values())), delimiterChars, itemPrefixChars); + } + public CharsOfLines(Args args) { + this( args, "\n", ""); + } + public CharsOfLines(Lines lines) { + this(lines, "\n", ""); + } + public CharsOfLines(List list) { + this(list, "\n", ""); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfPathWithComment.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfPathWithComment.java new file mode 100644 index 0000000..4430ee9 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsOfPathWithComment.java @@ -0,0 +1,11 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.nio.file.Path; + +public class CharsOfPathWithComment extends CharsOf { + public CharsOfPathWithComment(Path origin, CharSequence comment) { + super(()->{ + return origin.toAbsolutePath().toString() + " # " + comment; + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsQuotedToRegexPattern.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsQuotedToRegexPattern.java new file mode 100644 index 0000000..1da53ac --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsQuotedToRegexPattern.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +public class CharsQuotedToRegexPattern extends CharSequenceEnvelope { + public CharsQuotedToRegexPattern(CharSequence origin) { + super(() -> { + return String.valueOf(origin).replaceAll("[\\W]", "\\\\$0"); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsWithBoundary.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsWithBoundary.java new file mode 100644 index 0000000..253b0c3 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsWithBoundary.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.text.MessageFormat; + +public class CharsWithBoundary extends CharSequenceEnvelope { + public CharsWithBoundary(CharSequence origin, CharSequence boundaryChars) { + super(()-> MessageFormat.format("{1}{0}{1}", origin, boundaryChars)); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsWithMaskedCredentials.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsWithMaskedCredentials.java new file mode 100644 index 0000000..1032cec --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CharsWithMaskedCredentials.java @@ -0,0 +1,31 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import ru.fusionsoft.dbgit.integration.primitives.credentials.specific.CredsOfGitTestRepo; +import ru.fusionsoft.dbgit.integration.primitives.credentials.specific.CredsOfPgTestDatabase; + +public class CharsWithMaskedCredentials extends CharSequenceEnvelope { + public CharsWithMaskedCredentials(CharSequence origin) { + super(() -> { + final List replacementsList = new ArrayList<>(); + try { + replacementsList.add(new CredsOfGitTestRepo().password()); + } catch (Throwable e) { } + try { + replacementsList.add(new CredsOfPgTestDatabase().password()); + } catch (Throwable e) { } + + return String + .valueOf(origin) + .replaceAll( + replacementsList + .stream() + .map(CharsQuotedToRegexPattern::new) + .collect(Collectors.joining("|")), + "****" + ); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CommitsFromRepo.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CommitsFromRepo.java new file mode 100644 index 0000000..3dc0667 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/CommitsFromRepo.java @@ -0,0 +1,51 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import com.google.common.collect.Lists; +import java.util.List; +import java.util.stream.Collectors; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; +import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; +import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.transport.RefSpec; + +public class CommitsFromRepo { + private final CharSequence repoUrl; + private final CharSequence branchName; + + public CommitsFromRepo(CharSequence repoUrl, CharSequence branchName) { + this.repoUrl = repoUrl; + this.branchName = branchName; + } + + public final List names() throws Exception { + final String treeName = "refs/heads/" + branchName; // tag or branch + try ( + final Git git = new Git( + new InMemoryRepository( + new DfsRepositoryDescription() + ) + ) + ) { + git.fetch() + .setRemote(String.valueOf(repoUrl)) + .setRefSpecs( + new RefSpec( + "+refs/heads/" + branchName + + ":refs/heads/" + branchName + ) + ) + .call(); + + return Lists.newArrayList( + git + .log() + .add(git.getRepository().resolve(treeName)) + .call() + ) + .stream() + .map(AnyObjectId::getName) + .collect(Collectors.toList()); + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/Lines.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/Lines.java new file mode 100644 index 0000000..0f035f7 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/Lines.java @@ -0,0 +1,7 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.util.List; + +public interface Lines { + List list() throws Exception; +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesFromInputStream.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesFromInputStream.java new file mode 100644 index 0000000..5a227b3 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesFromInputStream.java @@ -0,0 +1,40 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.io.BufferedReader; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.util.LinkedList; +import java.util.List; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; +import ru.fusionsoft.dbgit.integration.primitives.StickyScalar; + +public class LinesFromInputStream implements Lines { + private final Scalar> listScalar; + public LinesFromInputStream(InputStream origin, String codepageName) { + this.listScalar = new StickyScalar<>( + () -> { + try ( + final BufferedReader reader = new BufferedReader(new InputStreamReader(origin, codepageName)); + ) { + final LinkedList lines = new LinkedList<>(); + String line; + while (( line = reader.readLine() ) != null) { + lines.add(line); + } + return lines; + } + } + ); + } + + public LinesFromInputStream(InputStream origin) { + this(origin, "default"); + } + + @Override + public final List list() throws Exception { + return listScalar.value(); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesOfString.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesOfString.java new file mode 100644 index 0000000..5bb1c0e --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesOfString.java @@ -0,0 +1,18 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.util.Arrays; +import java.util.List; +import ru.fusionsoft.dbgit.integration.primitives.chars.Lines; + +public class LinesOfString implements Lines { + private final String string; + + public LinesOfString(String string) { + this.string = string; + } + + @Override + public final List list() { + return Arrays.asList(string.split("\n")); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesOfUnsafeScalar.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesOfUnsafeScalar.java new file mode 100644 index 0000000..3a9a3a3 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/LinesOfUnsafeScalar.java @@ -0,0 +1,18 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars; + +import java.util.Arrays; +import java.util.List; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; + +public class LinesOfUnsafeScalar implements Lines { + private final Scalar charsScalar; + + public LinesOfUnsafeScalar(CharSequence charSequence) { + this.charsScalar = charSequence::toString; + } + + @Override + public final List list() throws Exception { + return Arrays.asList(String.valueOf(charsScalar.value()).split("\n")); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/NameOfDefaultTargetTestDatabase.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/NameOfDefaultTargetTestDatabase.java new file mode 100644 index 0000000..c21de49 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/NameOfDefaultTargetTestDatabase.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific; + +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public class NameOfDefaultTargetTestDatabase extends CharSequenceEnvelope { + public NameOfDefaultTargetTestDatabase() { + super(()->"test#databasegit"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/UrlOfGitTestRepo.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/UrlOfGitTestRepo.java new file mode 100644 index 0000000..fccf497 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/UrlOfGitTestRepo.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific; + +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public class UrlOfGitTestRepo extends CharSequenceEnvelope { + public UrlOfGitTestRepo() { + super(()-> "https://github.com/rocket-3/dbgit-test.git"); + } +} 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/CharsDbIgnoreDefault.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbIgnoreDefault.java new file mode 100644 index 0000000..018fe9f --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbIgnoreDefault.java @@ -0,0 +1,23 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit; + +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public class CharsDbIgnoreDefault extends CharSequenceEnvelope { + + public CharsDbIgnoreDefault() { + 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"; + }); + } +} 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/chars/specific/dbgit/CharsDbIgnoreWithTableData.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbIgnoreWithTableData.java new file mode 100644 index 0000000..1084bfe --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbIgnoreWithTableData.java @@ -0,0 +1,23 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit; + +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public class CharsDbIgnoreWithTableData extends CharSequenceEnvelope { + public CharsDbIgnoreWithTableData() { + 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/*.csv\n"; + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbLink.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbLink.java new file mode 100644 index 0000000..5d30711 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/dbgit/CharsDbLink.java @@ -0,0 +1,22 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.dbgit; + +import java.text.MessageFormat; +import ru.fusionsoft.dbgit.integration.primitives.Credentials; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public class CharsDbLink extends CharSequenceEnvelope { + public CharsDbLink(String url, String catalog, Credentials credentials) { + super(() -> { + return + MessageFormat.format( + "url=jdbc:postgresql://{0}/{1}\n" + + "user={2}\n" + + "password={3}\n" + , url + , catalog + , credentials.username() + , credentials.password() + ); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRun.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRun.java new file mode 100644 index 0000000..9925411 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRun.java @@ -0,0 +1,10 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.test; + +import java.text.MessageFormat; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; + +public abstract class LabelOfTestRun extends CharSequenceEnvelope { + public LabelOfTestRun(CharSequence text) { + super(()-> MessageFormat.format("[{0}]", text)); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunBrokenSubject.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunBrokenSubject.java new file mode 100644 index 0000000..38dff25 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunBrokenSubject.java @@ -0,0 +1,7 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.test; + +public class LabelOfTestRunBrokenSubject extends LabelOfTestRun { + public LabelOfTestRunBrokenSubject() { + super("SUBJECT ACCESS ERROR"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunExceptional.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunExceptional.java new file mode 100644 index 0000000..5baf441 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunExceptional.java @@ -0,0 +1,7 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.test; + +public class LabelOfTestRunExceptional extends LabelOfTestRun { + public LabelOfTestRunExceptional() { + super("TEST FAIL EXCEPTION"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunResult.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunResult.java new file mode 100644 index 0000000..600eb54 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/LabelOfTestRunResult.java @@ -0,0 +1,7 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.test; + +public class LabelOfTestRunResult extends LabelOfTestRun { + public LabelOfTestRunResult(boolean checkResult) { + super(checkResult ? "TEST OK" : "TEST FAIL"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestFormat.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestFormat.java new file mode 100644 index 0000000..53dd209 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestFormat.java @@ -0,0 +1,36 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.test; + +import java.text.MessageFormat; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOfLines; +import ru.fusionsoft.dbgit.integration.primitives.chars.LinesOfUnsafeScalar; + +public class ReportOfTestFormat extends CharSequenceEnvelope { + public ReportOfTestFormat(LabelOfTestRun label, CharSequence description, CharSequence subjectDetails, CharSequence testDetails) { + super(() -> { + final CharSequence subjectPart = String.valueOf(subjectDetails).trim().isEmpty() + ? "" + : new CharsOfLines(new LinesOfUnsafeScalar(subjectDetails), "", "\n| "); + + final CharSequence testPart = String.valueOf(testDetails).trim().isEmpty() + ? "" + : new CharsOfLines(new LinesOfUnsafeScalar(testDetails), "", "\n| "); + + return MessageFormat.format( + "{0} \"{1}\"{2}{3}" + , label + , description + , subjectPart + , testPart + ); + }); + } + + public ReportOfTestFormat(LabelOfTestRun label, CharSequence description, CharSequence details) { + this(label, description, details, ""); + } + + public ReportOfTestFormat(LabelOfTestRun label, CharSequence description) { + this(label, description, ""); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestGroupRun.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestGroupRun.java new file mode 100644 index 0000000..9601a7c --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestGroupRun.java @@ -0,0 +1,46 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.test; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.platform.commons.util.ExceptionUtils; +import ru.fusionsoft.dbgit.integration.primitives.SimpleTestResult; +import ru.fusionsoft.dbgit.integration.primitives.Test; +import ru.fusionsoft.dbgit.integration.primitives.TestResult; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOf; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOfConsoleWhenRunning; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsWithMaskedCredentials; + +public class ReportOfTestGroupRun extends CharSequenceEnvelope { + @SafeVarargs + public ReportOfTestGroupRun(CharSequence description, Subj subject, Test... tests) { + super(() -> { + return new CharsWithMaskedCredentials(new CharsOf(() -> { + try { + final String subjectConsoleOutput = String.valueOf(new CharsOfConsoleWhenRunning(subject::toString)); + + final List testResults = Arrays + .stream(tests) + .map(x -> new SimpleTestResult<>(subject, x)) + .collect(Collectors.toList()); + + return new ReportOfTestFormat( + new LabelOfTestRunResult(testResults.stream().allMatch(TestResult::value)), + description, + subjectConsoleOutput, + testResults.stream().map(TestResult::text).collect(Collectors.joining("\n")) + ); + } catch (CharsOfConsoleWhenRunning.CharsOfConsoleWhenRunningException e) { + return new ReportOfTestFormat( + new LabelOfTestRunBrokenSubject(), + description, + e.getMessage(), + ExceptionUtils.readStackTrace(e.getCause().getCause()) + ); + } + + })); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestRun.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestRun.java new file mode 100644 index 0000000..53b44c4 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/chars/specific/test/ReportOfTestRun.java @@ -0,0 +1,47 @@ +package ru.fusionsoft.dbgit.integration.primitives.chars.specific.test; + +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.platform.commons.util.ExceptionUtils; +import ru.fusionsoft.dbgit.integration.primitives.Test; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharSequenceEnvelope; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOf; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOfConsoleWhenRunning; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsWithMaskedCredentials; + +public class ReportOfTestRun extends CharSequenceEnvelope { + public ReportOfTestRun(Subj subject, Test test) { + super(() -> { + return new CharsWithMaskedCredentials(new CharsOf(() -> { + + try { + final CharSequence subjDetails = String.valueOf(new CharsOfConsoleWhenRunning(subject::toString)); + try { + final AtomicBoolean value = new AtomicBoolean(false); + final CharSequence testDetails = String.valueOf(new CharsOfConsoleWhenRunning(()-> value.set(test.value(subject)))); + final LabelOfTestRun label = new LabelOfTestRunResult(value.get()); + return new ReportOfTestFormat( + label, + test.description(), + subjDetails, + testDetails + ); + } catch (Throwable testThrowable) { + return new ReportOfTestFormat( + new LabelOfTestRunExceptional(), + test.description(), + ExceptionUtils.readStackTrace(testThrowable) + ); + } + } catch (CharsOfConsoleWhenRunning.CharsOfConsoleWhenRunningException e) { + return new ReportOfTestFormat( + new LabelOfTestRunBrokenSubject(), + test.description(), + e.getMessage(), + ExceptionUtils.readStackTrace(e.getCause().getCause()) + ); + } + + })); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsEnvelope.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsEnvelope.java new file mode 100644 index 0000000..638e961 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsEnvelope.java @@ -0,0 +1,25 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials; + +import ru.fusionsoft.dbgit.integration.primitives.Credentials; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalar; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalarOf; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; +import ru.fusionsoft.dbgit.integration.primitives.StickyScalar; + +public class CredentialsEnvelope implements Credentials { + private final SafeScalar credentialsScalar; + + public CredentialsEnvelope(Scalar credentialsScalar) { + this.credentialsScalar = new SafeScalarOf<>(new StickyScalar<>(credentialsScalar)); + } + + @Override + public final String username() { + return this.credentialsScalar.value().username(); + } + + @Override + public final String password() { + return this.credentialsScalar.value().password(); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsFromFile.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsFromFile.java new file mode 100644 index 0000000..8c30ded --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsFromFile.java @@ -0,0 +1,19 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.files.FileContent; + +public class CredentialsFromFile extends CredentialsEnvelope { + + public CredentialsFromFile(Path secretFilePath) { + super(()-> { + final String[] lines = new FileContent(secretFilePath) + .text() + .split("\n"); + return new SimpleCredentials( + lines[0].trim(), + lines[1].trim() + ); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsFromProperties.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsFromProperties.java new file mode 100644 index 0000000..077be9b --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/CredentialsFromProperties.java @@ -0,0 +1,14 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials; + +public class CredentialsFromProperties extends CredentialsEnvelope { + public CredentialsFromProperties(String usrPropName, String pwdPropName) { + super(()-> { + final String usrValue = System.getProperty(usrPropName); + final String pwdValue = System.getProperty(pwdPropName); + if (usrValue == null || usrValue.isEmpty() || pwdValue == null || pwdValue.isEmpty()) { + throw new Exception("Could not obtain credentials from props"); + } + return new SimpleCredentials(usrValue, pwdValue); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/SimpleCredentials.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/SimpleCredentials.java new file mode 100644 index 0000000..bdd2006 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/SimpleCredentials.java @@ -0,0 +1,24 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials; + +import ru.fusionsoft.dbgit.integration.primitives.Credentials; + +public class SimpleCredentials implements Credentials { + + private final String username; + private final String password; + + public SimpleCredentials(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + public final String username() { + return this.username; + } + + @Override + public final String password() { + return this.password; + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromGitMvnDProps.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromGitMvnDProps.java new file mode 100644 index 0000000..98ac81c --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromGitMvnDProps.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials.specific; + +import ru.fusionsoft.dbgit.integration.primitives.credentials.CredentialsFromProperties; + +public class CredsFromGitMvnDProps extends CredentialsFromProperties { + public CredsFromGitMvnDProps() { + super("gitUser", "gitPass"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromGitSecretFile.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromGitSecretFile.java new file mode 100644 index 0000000..a265b83 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromGitSecretFile.java @@ -0,0 +1,10 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials.specific; + +import ru.fusionsoft.dbgit.integration.primitives.credentials.CredentialsFromFile; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.CurrentWorkingDirectory; + +public class CredsFromGitSecretFile extends CredentialsFromFile { + public CredsFromGitSecretFile() { + super(new CurrentWorkingDirectory().resolve("../gitSecret.txt")); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromPgMvnDProps.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromPgMvnDProps.java new file mode 100644 index 0000000..389ae9a --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromPgMvnDProps.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials.specific; + +import ru.fusionsoft.dbgit.integration.primitives.credentials.CredentialsFromProperties; + +public class CredsFromPgMvnDProps extends CredentialsFromProperties { + public CredsFromPgMvnDProps() { + super("pgUser", "pgPass"); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromPgSecretFile.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromPgSecretFile.java new file mode 100644 index 0000000..51ba303 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsFromPgSecretFile.java @@ -0,0 +1,10 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials.specific; + +import ru.fusionsoft.dbgit.integration.primitives.credentials.CredentialsFromFile; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.CurrentWorkingDirectory; + +public class CredsFromPgSecretFile extends CredentialsFromFile { + public CredsFromPgSecretFile() { + super(new CurrentWorkingDirectory().resolve("../pgSecret.txt")); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsOfGitTestRepo.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsOfGitTestRepo.java new file mode 100644 index 0000000..c81dc57 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsOfGitTestRepo.java @@ -0,0 +1,25 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials.specific; + +import ru.fusionsoft.dbgit.integration.primitives.Credentials; +import ru.fusionsoft.dbgit.integration.primitives.credentials.CredentialsEnvelope; +import ru.fusionsoft.dbgit.integration.primitives.credentials.SimpleCredentials; + +public class CredsOfGitTestRepo extends CredentialsEnvelope { + public CredsOfGitTestRepo() { + super(() -> { + try { + final Credentials creds = new CredsFromGitMvnDProps(); + return new SimpleCredentials( + creds.username(), + creds.password() + ); + } catch (Throwable e) { + final Credentials creds = new CredsFromGitSecretFile(); + return new SimpleCredentials( + creds.username(), + creds.password() + ); + } + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsOfPgTestDatabase.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsOfPgTestDatabase.java new file mode 100644 index 0000000..334b1ac --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/credentials/specific/CredsOfPgTestDatabase.java @@ -0,0 +1,25 @@ +package ru.fusionsoft.dbgit.integration.primitives.credentials.specific; + +import ru.fusionsoft.dbgit.integration.primitives.Credentials; +import ru.fusionsoft.dbgit.integration.primitives.credentials.CredentialsEnvelope; +import ru.fusionsoft.dbgit.integration.primitives.credentials.SimpleCredentials; + +public class CredsOfPgTestDatabase extends CredentialsEnvelope { + public CredsOfPgTestDatabase() { + super(() -> { + try { + final Credentials creds = new CredsFromPgMvnDProps(); + return new SimpleCredentials( + creds.username(), + creds.password() + ); + } catch (Throwable e) { + final Credentials creds = new CredsFromPgSecretFile(); + return new SimpleCredentials( + creds.username(), + creds.password() + ); + } + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/AutoDeletingTempFilePath.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/AutoDeletingTempFilePath.java new file mode 100644 index 0000000..9fabb1d --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/AutoDeletingTempFilePath.java @@ -0,0 +1,33 @@ +package ru.fusionsoft.dbgit.integration.primitives.files; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Random; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOf; +import ru.fusionsoft.dbgit.integration.primitives.path.PathEnvelope; + +public class AutoDeletingTempFilePath extends PathEnvelope implements AutoCloseable { + + public AutoDeletingTempFilePath(CharSequence fileName) { + super(()-> Paths.get(String.valueOf(fileName))); + } + public AutoDeletingTempFilePath(Path directory, CharSequence prefix) { + this( + new CharsOf<>( ()-> { + return directory.resolve( + prefix + + String.format("#%06x", new Random().nextInt(256 * 256 * 256)) + ) + .toAbsolutePath() + .toString(); + }) + ); + } + + @Override + public final void close() throws IOException { + Files.deleteIfExists(this.toFile().toPath()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/DbGitMetaFiles.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/DbGitMetaFiles.java new file mode 100644 index 0000000..61ebac4 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/DbGitMetaFiles.java @@ -0,0 +1,47 @@ +package ru.fusionsoft.dbgit.integration.primitives.files; + + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class DbGitMetaFiles implements TextResourceGroup { + private final Path workingDirectory; + + public DbGitMetaFiles(Path workingDirectory) { + this.workingDirectory = workingDirectory; + } + + @Override + public final void add(String name, String content) throws IOException { + new FileContent(this.workingDirectory, name).updateText(content); + } + + @Override + public final void clean() throws IOException { + for (TextResource textFile : this.all().values()) { + textFile.delete(); + } + } + + @Override + public final TextResource file(String... name){ + return new FileContent(this.workingDirectory, name); +} + + @Override + public final Map all() throws IOException { + try (Stream paths = Files.walk(this.workingDirectory.resolve(".dbgit"))) { + return paths + .filter( x->x.getParent().getParent().toFile().getName().equals(".dbgit") ) + .filter(Files::isRegularFile ) + .peek(System.out::println) + .collect(Collectors.toMap( x->x.toFile().getName(), FileContent::new) ); + } + } + + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/FileContent.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/FileContent.java new file mode 100644 index 0000000..d9edd6d --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/FileContent.java @@ -0,0 +1,43 @@ +package ru.fusionsoft.dbgit.integration.primitives.files; + +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; + +public class FileContent implements TextResource { + private final File file; + + public FileContent(final File file) { + this.file = file; + } + + public FileContent(final Path path) { + this(path.toFile()); + } + + public FileContent(final Path workingDirectory, final String... name) { + this(workingDirectory.resolve(String.join("//", name))); + } + + @Override + public final String text() throws IOException { + return FileUtils.readFileToString(this.file); + } + + @Override + public final TextResource updateText(final String content) throws IOException { + this.file.getParentFile().mkdirs(); + FileUtils.writeStringToFile(this.file, content); + return this; + } + + @Override + public final TextResource delete() throws IOException { + if (this.file.exists()) { + FileUtils.forceDelete(this.file); + } + return this; + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextFileTest.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextFileTest.java new file mode 100644 index 0000000..c148387 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextFileTest.java @@ -0,0 +1,56 @@ +package ru.fusionsoft.dbgit.integration.primitives.files; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.CurrentWorkingDirectory; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; + +public class TextFileTest { + + private final Path path; + + public TextFileTest(Path path) { + this.path = path; + } + + public TextFileTest() { + this(new CurrentWorkingDirectory()); + } + + @Test + public void createsFile() throws IOException { + String relativePath = ".dbgit/.dblink"; + + Assertions.assertEquals( + new FileContent(this.path, relativePath) + .updateText("ABC") + .text(), + + FileUtils.readFileToString( + this.path.resolve(relativePath).toFile() + ) + ); + } + + @Test + public void updatesContent() throws IOException { + File file = this.path.resolve("file").toFile(); + String content = "CBD"; + + new FileContent(file).updateText(content); + + Assertions.assertEquals( + content, + FileUtils.readFileToString(file) + ); + } + + @Test + public void pathTest() { + System.out.println(); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextResource.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextResource.java new file mode 100644 index 0000000..a7f16fb --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextResource.java @@ -0,0 +1,11 @@ +package ru.fusionsoft.dbgit.integration.primitives.files; + + +import java.io.IOException; + +public interface TextResource { + String text() throws IOException; + TextResource updateText(String content) throws IOException; + TextResource delete() throws IOException; + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextResourceGroup.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextResourceGroup.java new file mode 100644 index 0000000..cbf5b88 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/files/TextResourceGroup.java @@ -0,0 +1,11 @@ +package ru.fusionsoft.dbgit.integration.primitives.files; + +import java.io.IOException; +import java.util.Map; + +public interface TextResourceGroup { + void add(String name, String content) throws IOException; + void clean() throws IOException; + TextResource file(String... name); + Map all() throws IOException; +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchAssertsNotMvnProjectRoot.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchAssertsNotMvnProjectRoot.java new file mode 100644 index 0000000..f351279 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchAssertsNotMvnProjectRoot.java @@ -0,0 +1,26 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Patch; + +public class PathPatchAssertsNotMvnProjectRoot implements Patch { + @Override + public final void apply(Path root) throws Exception { + if ( + root.resolve(".git").toFile().exists() && + root.resolve("pom.xml").toFile().exists() + ) { + throw new PathIsProjectRootException(root); + } + } + + private static class PathIsProjectRootException extends RuntimeException { + PathIsProjectRootException(Path path) { + super( + "\nGiven path " + path.toString() + " " + + "points to a project root directory.\n" + + "I'm here not to allow that." + ); + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchCloningGitRepo.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchCloningGitRepo.java new file mode 100644 index 0000000..a58c5f9 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchCloningGitRepo.java @@ -0,0 +1,38 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; + +public class PathPatchCloningGitRepo extends PatchSequential { + + public PathPatchCloningGitRepo(final String repoUrl, final String branchName, PrintStream printStream) { + super( + new PathPatchRunningExecutable( + "git", + new ArgsExplicit( + "clone", + repoUrl, + "." + ), + printStream + ), + new PathPatchRunningExecutable( + "git", + new ArgsExplicit( + "reset", + "--hard", + branchName + ), + printStream + ) + + ); + } + + public PathPatchCloningGitRepo(final String repoUrl, final String branchName) { + this(repoUrl, branchName, new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchConfiguringDbGit.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchConfiguringDbGit.java new file mode 100644 index 0000000..9979cc3 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchConfiguringDbGit.java @@ -0,0 +1,18 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; + +public class PathPatchConfiguringDbGit extends PatchSequential { + + public PathPatchConfiguringDbGit(final String linkContent, final String ignoreContent, final String configContent, final String indexContent) { + super( + new PathPatchCreatingFile(".dbgit/.dblink", linkContent), + new PathPatchCreatingFile(".dbgit/.dbignore", ignoreContent), + new PathPatchCreatingFile(".dbgit/.dbindex", indexContent), + new PathPatchCreatingFile(".dbgit/dbgitconfig", configContent) + ); + + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchCreatingFile.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchCreatingFile.java new file mode 100644 index 0000000..f77e472 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchCreatingFile.java @@ -0,0 +1,41 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.File; +import java.io.PrintStream; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.stream.Collectors; +import org.apache.commons.io.FileUtils; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOfPathWithComment; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathPatchCreatingFile extends PathPatchWithPrintStream { + private final String name; + private final String content; + + public PathPatchCreatingFile(final String name, final CharSequence content, PrintStream printStream) { + super(printStream); + this.name = name; + this.content = String.valueOf(content); + } + + public PathPatchCreatingFile(final String name, final CharSequence content) { + this(name, content, new DefaultPrintStream()); + } + + @Override + public final void apply(final Path root) throws Exception { + this.printStream.println( + new CharsOfPathWithComment( + root, + "writing file " + name + " with content:\n" + + Arrays.stream(content.split("\n")) + .map( x-> "> " + x) + .collect(Collectors.joining(System.getProperty("line.separator"))) + ) + ); + final File file = root.resolve(this.name).toFile(); + file.getParentFile().mkdirs(); + FileUtils.writeStringToFile(file, this.content); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchDeletingFiles.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchDeletingFiles.java new file mode 100644 index 0000000..5400d90 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchDeletingFiles.java @@ -0,0 +1,30 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.File; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collection; +import org.apache.commons.io.FileUtils; +import ru.fusionsoft.dbgit.integration.primitives.Patch; + +public class PathPatchDeletingFiles implements Patch { + private final Collection names; + + private PathPatchDeletingFiles(Collection names) { + this.names = names; + } + + public PathPatchDeletingFiles(String... names) { + this(Arrays.asList(names)); + } + + @Override + public final void apply(Path root) throws Exception { + for (String name : this.names) { + final File file = root.resolve(name).toFile(); + if (file.exists()) { + FileUtils.forceDelete(file); + } + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchDeletingFilesWildcard.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchDeletingFilesWildcard.java new file mode 100644 index 0000000..aee125f --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchDeletingFilesWildcard.java @@ -0,0 +1,26 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.nio.file.Path; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.WildcardFileFilter; +import ru.fusionsoft.dbgit.integration.primitives.Patch; + +public class PathPatchDeletingFilesWildcard implements Patch { + private final FileFilter wildcardFileFilter; + + public PathPatchDeletingFilesWildcard(String mask) { + this.wildcardFileFilter = new WildcardFileFilter(mask); + } + + @Override + public final void apply(Path root) throws Exception { + final File[] files = root.toFile().listFiles((FilenameFilter) wildcardFileFilter); + if(files != null) + for (final File file : files) { + FileUtils.forceDelete(file); + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningDbGit.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningDbGit.java new file mode 100644 index 0000000..50a0a90 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningDbGit.java @@ -0,0 +1,42 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsRunningCommand; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithAppend; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.PathOfBuiltDbGitExecutable; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.CurrentWorkingDirectory; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathPatchRunningDbGit extends PathPatchRunningProcessFrom { + public PathPatchRunningDbGit(Args args, Path executablePath, PrintStream printStream) { + super( + new ArgsWithAppend( + new ArgsRunningCommand(executablePath), + args + ), + printStream + ); + } + + public PathPatchRunningDbGit(Args args, Path executablePath) { + this( + args, + executablePath, + System.out + ); + } + + public PathPatchRunningDbGit(Args args, PrintStream printStream) { + this( + args, + new PathOfBuiltDbGitExecutable(new CurrentWorkingDirectory()), + printStream + ); + } + + public PathPatchRunningDbGit(Args args) { + this(args, new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningExecutable.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningExecutable.java new file mode 100644 index 0000000..9a38764 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningExecutable.java @@ -0,0 +1,21 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsRunningCommand; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithAppend; + +public class PathPatchRunningExecutable extends PathPatchRunningProcessFrom { + + public PathPatchRunningExecutable(CharSequence commandName, Args commandArgs, PrintStream printStream) { + super( + new ArgsWithAppend( + new ArgsRunningCommand(commandName), + commandArgs + ), + printStream + ); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningGit.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningGit.java new file mode 100644 index 0000000..c64f90e --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningGit.java @@ -0,0 +1,25 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.PrintStream; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathPatchRunningGit extends PathPatchRunningExecutable { + public PathPatchRunningGit(Args gitArgs, PrintStream printStream) { + super( + "git", + gitArgs, + printStream + ); + } + + public PathPatchRunningGit(Args gitArgs) { + this(gitArgs, new DefaultPrintStream()); + } + + public PathPatchRunningGit(CharSequence... gitArgs) { + this(new ArgsExplicit(gitArgs)); + } +} + diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningProcessFrom.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningProcessFrom.java new file mode 100644 index 0000000..7dc91fa --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchRunningProcessFrom.java @@ -0,0 +1,71 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.Patch; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOf; +import ru.fusionsoft.dbgit.integration.primitives.chars.CharsOfLines; +import ru.fusionsoft.dbgit.integration.primitives.files.AutoDeletingTempFilePath; + +public class PathPatchRunningProcessFrom implements Patch { + + private final Args processRunCommandLine; + private final PrintStream printStream; + + public PathPatchRunningProcessFrom(Args processRunCommandLine, PrintStream printStream) { + this.processRunCommandLine = processRunCommandLine; + this.printStream = printStream; + } + + @Override + public final void apply(Path workingDirectory) throws Exception { + final Consumer outputConsumer = printStream::println; + outputConsumer.accept(MessageFormat.format( + "{0} # {1}", + workingDirectory.toString(), + String.join(" ", processRunCommandLine.values()) + )); + + try ( + final AutoDeletingTempFilePath tempOutPath = new AutoDeletingTempFilePath(workingDirectory.resolve("../"), "out"); + final AutoDeletingTempFilePath tempErrPath = new AutoDeletingTempFilePath(workingDirectory.resolve("../"), "err"); + ) { + + final Process process = new ProcessBuilder() + .directory(workingDirectory.toFile()) + .command( + Arrays.stream(processRunCommandLine.values()) + .map(String::valueOf) + .collect(Collectors.toList()) + ) + .redirectOutput(tempOutPath.toFile()) + .redirectError(tempErrPath.toFile()) + .start(); + process.getOutputStream().close(); + + final int exitCode = process.waitFor(); + outputConsumer.accept(new CharsOfLines(Files.readAllLines(tempOutPath.toFile().toPath()), "\n", "> ")); + + if (exitCode != 0) { + throw new Exception(MessageFormat.format( + "Process exited with error, code {0}\nErrors: {1}", + exitCode, + new CharsOf<>(()->{ + final List lines = Files.readAllLines(tempErrPath.toFile().toPath()); + return lines.isEmpty() + ? "...error stream was empty" + : new CharsOfLines(lines, "", "\n> "); + }) + )); + } + + } + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchWithPrintStream.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchWithPrintStream.java new file mode 100644 index 0000000..12d4586 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/PathPatchWithPrintStream.java @@ -0,0 +1,13 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Patch; + +public abstract class PathPatchWithPrintStream implements Patch { + protected final PrintStream printStream; + + public PathPatchWithPrintStream(PrintStream printStream) { + this.printStream = printStream; + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitAdd.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitAdd.java new file mode 100644 index 0000000..b4ac2cd --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitAdd.java @@ -0,0 +1,21 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch.specific; + +import java.io.PrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitAdd; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathPatchDbGitAdd extends PathPatchRunningDbGit { + public PathPatchDbGitAdd(CharSequence mask, PrintStream printStream) { + super(new ArgsDbGitAdd(mask), printStream); + } + public PathPatchDbGitAdd(PrintStream printStream) { + super(new ArgsDbGitAdd(), printStream); + } + public PathPatchDbGitAdd(CharSequence mask) { + this(mask, new DefaultPrintStream()); + } + public PathPatchDbGitAdd() { + this(new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckout.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckout.java new file mode 100644 index 0000000..6e76963 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckout.java @@ -0,0 +1,18 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch.specific; + +import java.io.PrintStream; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitCheckout; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; + +public class PathPatchDbGitCheckout extends PathPatchRunningDbGit { + public PathPatchDbGitCheckout(ArgsDbGitCheckout args, PrintStream printStream) { + super(args, printStream); + } + public PathPatchDbGitCheckout(ArgsDbGitCheckout args) { + this(args, new DefaultPrintStream()); + } + public PathPatchDbGitCheckout(CharSequence... args) { + this(new ArgsDbGitCheckout(args)); + } +} 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)) + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckoutReset.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckoutReset.java new file mode 100644 index 0000000..ad63502 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCheckoutReset.java @@ -0,0 +1,25 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch.specific; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitCheckout; + +public class PathPatchDbGitCheckoutReset extends PatchSequential { + public PathPatchDbGitCheckoutReset(ArgsDbGitCheckout checkoutArgs, PrintStream printStream) { + super( + new PathPatchDbGitCheckout(checkoutArgs, printStream), + new PathPatchDbGitReset("-hard") + ); + } + + public PathPatchDbGitCheckoutReset(ArgsDbGitCheckout checkoutArgs) { + this(checkoutArgs, new DefaultPrintStream()); + } + + public PathPatchDbGitCheckoutReset(CharSequence... checkoutParams) { + this(new ArgsDbGitCheckout(checkoutParams)); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitClonesRepo.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitClonesRepo.java new file mode 100644 index 0000000..776872f --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitClonesRepo.java @@ -0,0 +1,41 @@ +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.ArgsDbGitAddRemote; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitClone; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchAssertsNotMvnProjectRoot; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchDeletingFilesWildcard; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathPatchDbGitClonesRepo extends PatchSequential { + public PathPatchDbGitClonesRepo(CharSequence repoUrl, ArgsDbGitAddRemote addRemoteArgs, PrintStream printStream) { + super( + new PathPatchAssertsNotMvnProjectRoot(), + new PathPatchDeletingFilesWildcard( + "*" + ), + new PathPatchRunningDbGit( + new ArgsDbGitClone(repoUrl), + printStream + ), + new PathPatchRunningDbGit( + addRemoteArgs, + printStream + ) + ); + } + public PathPatchDbGitClonesRepo(CharSequence repoUrl, PrintStream printStream) { + super( + new PathPatchRunningDbGit( + new ArgsDbGitClone(repoUrl), + printStream + ) + ); + } + public PathPatchDbGitClonesRepo(CharSequence repoUrl, ArgsDbGitAddRemote addRemoteArgs) { + this(repoUrl, addRemoteArgs, new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCommit.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCommit.java new file mode 100644 index 0000000..008a4b6 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitCommit.java @@ -0,0 +1,16 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch.specific; + +import java.io.PrintStream; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; + +public class PathPatchDbGitCommit extends PathPatchRunningDbGit { + public PathPatchDbGitCommit(CharSequence message, PrintStream printStream) { + super(new ArgsExplicit("commit", "-m", message), printStream); + } + + public PathPatchDbGitCommit(CharSequence message) { + this(message, new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitInitializesRepo.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitInitializesRepo.java new file mode 100644 index 0000000..8df7145 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitInitializesRepo.java @@ -0,0 +1,38 @@ +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.ArgsDbGitInit; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitLink; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchAssertsNotMvnProjectRoot; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchDeletingFilesWildcard; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathPatchDbGitInitializesRepo extends PatchSequential { + public PathPatchDbGitInitializesRepo(ArgsDbGitLink linkArgs, PrintStream printStream) { + super( + new PathPatchAssertsNotMvnProjectRoot(), + new PathPatchDeletingFilesWildcard("*"), + new PathPatchRunningDbGit(new ArgsDbGitInit(), printStream), + new PathPatchRunningDbGit(linkArgs, printStream) + ); + } + + public PathPatchDbGitInitializesRepo(PrintStream printStream) { + super( + new PathPatchAssertsNotMvnProjectRoot(), + new PathPatchDeletingFilesWildcard("*"), + new PathPatchRunningDbGit(new ArgsDbGitInit(), printStream) + ); + } + + public PathPatchDbGitInitializesRepo(ArgsDbGitLink linkArgs) { + this(linkArgs, new DefaultPrintStream()); + } + + public PathPatchDbGitInitializesRepo() { + this(new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitLink.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitLink.java new file mode 100644 index 0000000..4b44990 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitLink.java @@ -0,0 +1,17 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch.specific; + +import java.io.PrintStream; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitLink; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; + +public class PathPatchDbGitLink extends PathPatchRunningDbGit { + + public PathPatchDbGitLink(ArgsDbGitLink args, PrintStream printStream) { + super(args, printStream); + } + + public PathPatchDbGitLink(ArgsDbGitLink args) { + this(args, new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitReset.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitReset.java new file mode 100644 index 0000000..1faf9f6 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitReset.java @@ -0,0 +1,20 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch.specific; + +import java.io.PrintStream; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitReset; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; + +public class PathPatchDbGitReset extends PathPatchRunningDbGit { + public PathPatchDbGitReset(CharSequence resetMode, PrintStream printStream) { + super(new ArgsDbGitReset(resetMode), printStream); + } + + public PathPatchDbGitReset(CharSequence resetMode) { + this(resetMode, new DefaultPrintStream()); + } + + public PathPatchDbGitReset() { + this("hard", new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitRestore.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitRestore.java new file mode 100644 index 0000000..b750867 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchDbGitRestore.java @@ -0,0 +1,20 @@ +package ru.fusionsoft.dbgit.integration.primitives.patch.specific; + +import java.io.PrintStream; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitRestore; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; + +public class PathPatchDbGitRestore extends PathPatchRunningDbGit { + public PathPatchDbGitRestore(ArgsDbGitRestore restoreArgs, PrintStream printStream) { + super(restoreArgs, printStream); + } + + public PathPatchDbGitRestore(ArgsDbGitRestore restoreArgs) { + this(restoreArgs, new DefaultPrintStream()); + } + + public PathPatchDbGitRestore(CharSequence... restoreCommandArgs) { + this(new ArgsDbGitRestore(restoreCommandArgs), new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchGitCheckoutOrphan.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchGitCheckoutOrphan.java new file mode 100644 index 0000000..1301792 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/patch/specific/PathPatchGitCheckoutOrphan.java @@ -0,0 +1,27 @@ +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.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningGit; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathPatchGitCheckoutOrphan extends PatchSequential { + public PathPatchGitCheckoutOrphan(String newBranchName, PrintStream printStream) { + super( + new PathPatchRunningGit( + new ArgsExplicit("checkout", "--orphan", newBranchName), + printStream + ), + new PathPatchRunningGit( + new ArgsExplicit("rm", "-rf", "."), + printStream + ) + ); + } + + public PathPatchGitCheckoutOrphan(String newBranchName) { + this(newBranchName, new DefaultPrintStream()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterDbGitRun.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterDbGitRun.java new file mode 100644 index 0000000..7597278 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterDbGitRun.java @@ -0,0 +1,49 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.PathOfBuiltDbGitExecutable; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsRunningCommand; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithAppend; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.CurrentWorkingDirectory; + +public class PathAfterDbGitRun extends PathAfterProcessRun { + public PathAfterDbGitRun(Args args, Path executablePath, PrintStream printStream, Path workingDirectory) { + super( + new ArgsWithAppend( + new ArgsRunningCommand(executablePath), + args + ), + printStream, + workingDirectory + ); + } + + public PathAfterDbGitRun(Args args, PrintStream printStream, Path workingDirectory) { + this( + args, + new PathOfBuiltDbGitExecutable(new CurrentWorkingDirectory()), + printStream, + workingDirectory + ); + } + + public PathAfterDbGitRun(Args args, Path executablePath, Path workingDirectory) { + this( + args, + executablePath, + new DefaultPrintStream(), + workingDirectory + ); + } + + public PathAfterDbGitRun(Args args, Path workingDirectory) { + this( + args, + new PathOfBuiltDbGitExecutable(new CurrentWorkingDirectory()), + workingDirectory + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterGitRun.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterGitRun.java new file mode 100644 index 0000000..b396a77 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterGitRun.java @@ -0,0 +1,21 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsRunningCommand; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithAppend; + +public class PathAfterGitRun extends PathAfterProcessRun { + public PathAfterGitRun(Args gitArgs, PrintStream printStream, Path origin) { + super( + new ArgsWithAppend(new ArgsRunningCommand("git"), gitArgs), + printStream, + origin + ); + } + public PathAfterGitRun(Args gitArgs, Path origin) { + this(gitArgs, new DefaultPrintStream(), origin); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterProcessRun.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterProcessRun.java new file mode 100644 index 0000000..8ff963f --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathAfterProcessRun.java @@ -0,0 +1,15 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Args; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningProcessFrom; + +public class PathAfterProcessRun extends PathPatched { + public PathAfterProcessRun(Args processRunCommandLine, PrintStream printStream, Path origin) { + super( + origin, + new PathPatchRunningProcessFrom(processRunCommandLine, printStream) + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathEnvelope.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathEnvelope.java new file mode 100644 index 0000000..437eb2d --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathEnvelope.java @@ -0,0 +1,160 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import ru.fusionsoft.dbgit.integration.primitives.Scalar; +import ru.fusionsoft.dbgit.integration.primitives.StickyScalar; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalar; +import ru.fusionsoft.dbgit.integration.primitives.SafeScalarOf; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.nio.file.*; +import java.util.Iterator; + +public abstract class PathEnvelope implements Path { + + private final SafeScalar origin; + + public PathEnvelope(Scalar origin) { + this.origin = new SafeScalarOf<>( + new StickyScalar<>( + origin + ) + ); + } + + @Override + public String toString() { + return this.origin.value().toString(); + } + + @Override + public final FileSystem getFileSystem() { + return this.origin.value().getFileSystem(); + } + + @Override + public final boolean isAbsolute() { + return this.origin.value().isAbsolute(); + } + + @Override + public final Path getRoot() { + return this.origin.value().getRoot(); + } + + @Override + public final Path getFileName() { + return this.origin.value().getFileName(); + } + + @Override + public final Path getParent() { + return this.origin.value().getParent(); + } + + @Override + public final int getNameCount() { + return this.origin.value().getNameCount(); + } + + @Override + public final Path getName(int i) { + return this.origin.value().getName(i); + } + + @Override + public final Path subpath(int i, int i1) { + return this.origin.value().subpath(i, i1); + } + + @Override + public final boolean startsWith(Path path) { + return this.origin.value().startsWith(path); + } + + @Override + public final boolean endsWith(Path path) { + return this.origin.value().endsWith(path); + } + + @Override + public final Path normalize() { + return this.origin.value().normalize(); + } + + @Override + public final Path resolve(Path path) { + return this.origin.value().resolve(path); + } + + @Override + public final Path relativize(Path path) { + return this.origin.value().relativize(path); + } + + @Override + public final URI toUri() { + return this.origin.value().toUri(); + } + + @Override + public final Path toAbsolutePath() { + return this.origin.value().toAbsolutePath(); + } + + @Override + public final Path toRealPath(LinkOption... linkOptions) throws IOException { + return this.origin.value().toRealPath(linkOptions); + } + + @Override + public final WatchKey register(WatchService watchService, WatchEvent.Kind[] kinds, WatchEvent.Modifier... modifiers) throws IOException { + return this.origin.value().register(watchService,kinds,modifiers); + } + + @Override + public final int compareTo(Path path) { + return this.origin.value().compareTo(path); + } + + @Override + public final Iterator iterator() { + return origin.value().iterator(); + } + + @Override + public final WatchKey register(WatchService watcher, WatchEvent.Kind... events) throws IOException { + return this.origin.value().register(watcher, events); + } + + @Override + public final boolean startsWith(String other) { + return this.origin.value().startsWith(other); + } + + @Override + public final boolean endsWith(String other) { + return this.origin.value().endsWith(other); + } + + @Override + public final Path resolve(String other) { + return this.origin.value().resolve(other); + } + + @Override + public final Path resolveSibling(Path other) { + return this.origin.value().resolveSibling(other); + } + + @Override + public final Path resolveSibling(String other) { + return this.origin.value().resolveSibling(other); + } + + @Override + public final File toFile() { + return this.origin.value().toFile(); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathNotProjectRoot.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathNotProjectRoot.java new file mode 100644 index 0000000..fbf43dc --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathNotProjectRoot.java @@ -0,0 +1,15 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchAssertsNotMvnProjectRoot; + +public class PathNotProjectRoot extends PathPatched{ + public PathNotProjectRoot(Path origin) { + super(new PathPatchAssertsNotMvnProjectRoot(), origin); + } + + +} + + diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathOf.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathOf.java new file mode 100644 index 0000000..25beada --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathOf.java @@ -0,0 +1,15 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; + +public class PathOf extends PathEnvelope { + + public PathOf(Scalar origin) { + super(origin); + } + + public PathOf(String path, Path origin) { + super(()->origin.resolve(path).toAbsolutePath()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathPatched.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathPatched.java new file mode 100644 index 0000000..c202c5e --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathPatched.java @@ -0,0 +1,19 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Patch; +import ru.fusionsoft.dbgit.integration.primitives.PatchedScalar; + +public class PathPatched extends PathEnvelope { + + public PathPatched(final Path origin, final Patch patch) { + super( + new PatchedScalar<>(origin, patch) + ); + } + public PathPatched(final Patch patch, final Path origin) { + super( + new PatchedScalar<>(origin, patch) + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathPrintsToConsole.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathPrintsToConsole.java new file mode 100644 index 0000000..2f2f4f0 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathPrintsToConsole.java @@ -0,0 +1,26 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.nio.file.Path; +import java.util.Arrays; +import java.util.stream.Collectors; + + +public class PathPrintsToConsole extends PathEnvelope { + + public PathPrintsToConsole(String text, Path origin) { + super(() -> { + System.out.println(text); + return origin; + }); + } + public PathPrintsToConsole(Path origin) { + this( + "--> " + origin.toAbsolutePath() + + Arrays + .stream(origin.toFile().listFiles()) + .map( file -> file.getName() + (file.isDirectory() ? " (dir) " : "") ) + .collect(Collectors.joining("\n")), + origin + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathRelativeTo.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathRelativeTo.java new file mode 100644 index 0000000..9c41733 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathRelativeTo.java @@ -0,0 +1,21 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.nio.file.Path; +import java.nio.file.Paths; + +public class PathRelativeTo extends PathEnvelope { + public PathRelativeTo(Path to, Path origin) { + super(()-> { + return Paths.get( + to + .toAbsolutePath() + .toString() + ) + .relativize(Paths.get( + origin + .toAbsolutePath() + .toString() + )); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathWithFiles.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathWithFiles.java new file mode 100644 index 0000000..ae2d602 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathWithFiles.java @@ -0,0 +1,15 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; +import ru.fusionsoft.dbgit.integration.primitives.Scalar; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchCreatingFile; + +public class PathWithFiles extends PathPatched { + public PathWithFiles(PathPatchCreatingFile[] filePatches, Path origin) { + super(origin, new PatchSequential(filePatches)); + } + public PathWithFiles(PathPatchCreatingFile filePatch, Path origin){ + super(filePatch, origin); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathWithoutFiles.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathWithoutFiles.java new file mode 100644 index 0000000..49dd0d5 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/PathWithoutFiles.java @@ -0,0 +1,22 @@ +package ru.fusionsoft.dbgit.integration.primitives.path; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchDeletingFiles; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchDeletingFilesWildcard; + +public class PathWithoutFiles extends PathPatched { + + public PathWithoutFiles(String[] names, Path origin) { + super( + new PathPatchDeletingFiles(names), + origin + ); + } + + public PathWithoutFiles(String filterMask, Path origin) { + super( + new PathPatchDeletingFilesWildcard(filterMask), + origin + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/CurrentWorkingDirectory.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/CurrentWorkingDirectory.java new file mode 100644 index 0000000..f46b366 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/CurrentWorkingDirectory.java @@ -0,0 +1,12 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific; + +import java.nio.file.Paths; +import ru.fusionsoft.dbgit.integration.primitives.path.PathEnvelope; + +public class CurrentWorkingDirectory extends PathEnvelope { + public CurrentWorkingDirectory(){ + super(()-> { + return Paths.get(""); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/ProjectTestResourcesCleanDirectoryPath.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/ProjectTestResourcesCleanDirectoryPath.java new file mode 100644 index 0000000..d671371 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/ProjectTestResourcesCleanDirectoryPath.java @@ -0,0 +1,32 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific; + +import java.io.File; +import java.util.concurrent.ThreadLocalRandom; +import org.apache.commons.io.FileUtils; +import ru.fusionsoft.dbgit.integration.primitives.path.PathEnvelope; + +public class ProjectTestResourcesCleanDirectoryPath extends PathEnvelope { + + public ProjectTestResourcesCleanDirectoryPath() { + this( + String.format( + "%#X", + ThreadLocalRandom.current().nextInt( + 0, + 32 + ) + ) + ); + } + + public ProjectTestResourcesCleanDirectoryPath(String name) { + super(() -> { + final File directory = new File( + "target/itoutput/" + name + ); + directory.mkdirs(); + FileUtils.cleanDirectory(directory); + return directory.toPath().toAbsolutePath(); + }); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathOfBuiltDbGitExecutable.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathOfBuiltDbGitExecutable.java new file mode 100644 index 0000000..fc3a796 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathOfBuiltDbGitExecutable.java @@ -0,0 +1,13 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit; + +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.path.PathOf; + +public class PathOfBuiltDbGitExecutable extends PathOf { + public PathOfBuiltDbGitExecutable(Path dbGitProjectPath) { + super( + "target/dbgit/bin/dbgit", + dbGitProjectPath + ); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathWithDbGitNewRepoInitialized.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathWithDbGitNewRepoInitialized.java new file mode 100644 index 0000000..2a7031d --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathWithDbGitNewRepoInitialized.java @@ -0,0 +1,29 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.path.PathAfterDbGitRun; +import ru.fusionsoft.dbgit.integration.primitives.path.PathNotProjectRoot; +import ru.fusionsoft.dbgit.integration.primitives.path.PathWithoutFiles; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathWithDbGitNewRepoInitialized extends PathAfterDbGitRun { + public PathWithDbGitNewRepoInitialized(PrintStream printStream, Path workingDirectory) { + super( + new ArgsExplicit("init"), + printStream, + + new PathWithoutFiles( + "*", + new PathNotProjectRoot( + workingDirectory + ) + ) + ); + } + + public PathWithDbGitNewRepoInitialized(Path workingDirectory) { + this(new DefaultPrintStream(), workingDirectory); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathWithDbGitRepoCloned.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathWithDbGitRepoCloned.java new file mode 100644 index 0000000..cbdfb70 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/PathWithDbGitRepoCloned.java @@ -0,0 +1,30 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitAddRemote; +import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitClonesRepo; +import ru.fusionsoft.dbgit.integration.primitives.path.PathPatched; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; + +public class PathWithDbGitRepoCloned extends PathPatched { + public PathWithDbGitRepoCloned(CharSequence repoUrl, ArgsDbGitAddRemote addRemoteArgs, PrintStream printStream, Path origin) { + super( + new PathPatchDbGitClonesRepo(repoUrl, addRemoteArgs, printStream), + origin + ); + } + public PathWithDbGitRepoCloned(CharSequence repoUrl, PrintStream printStream, Path origin) { + super( + new PathPatchDbGitClonesRepo(repoUrl, printStream), + origin + ); + } + public PathWithDbGitRepoCloned(CharSequence repoUrl, ArgsDbGitAddRemote addRemoteArgs, Path origin) { + this(repoUrl, addRemoteArgs, new DefaultPrintStream(), origin); + } + public PathWithDbGitRepoCloned(CharSequence repoUrl, Path origin) { + this(repoUrl, new DefaultPrintStream(), origin); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitCheckoutAndLink.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitCheckoutAndLink.java new file mode 100644 index 0000000..48df385 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitCheckoutAndLink.java @@ -0,0 +1,34 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.scenarios; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitCheckout; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitLink; +import ru.fusionsoft.dbgit.integration.primitives.path.PathAfterDbGitRun; + +public class PathAfterDbGitCheckoutAndLink extends PathAfterDbGitRun { + public PathAfterDbGitCheckoutAndLink( + ArgsDbGitCheckout checkoutArgs, + ArgsDbGitLink linkArgs, + PrintStream printStream, + Path origin + ) { + super( + linkArgs, + printStream, + new PathAfterDbGitRun( + checkoutArgs, + origin + ) + ); + } + + public PathAfterDbGitCheckoutAndLink( + ArgsDbGitCheckout checkoutArgs, + ArgsDbGitLink linkArgs, + Path origin + ) { + this(checkoutArgs, linkArgs, new DefaultPrintStream(), origin); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitDumpsDbSchemaToGit.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitDumpsDbSchemaToGit.java new file mode 100644 index 0000000..041af4e --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitDumpsDbSchemaToGit.java @@ -0,0 +1,41 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.scenarios; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.Patch; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitAddRemote; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitLink; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchCreatingFile; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchRunningDbGit; +import ru.fusionsoft.dbgit.integration.primitives.patch.specific.PathPatchDbGitLink; +import ru.fusionsoft.dbgit.integration.primitives.path.PathPatched; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.PathWithDbGitRepoCloned; + +public class PathAfterDbGitDumpsDbSchemaToGit extends PathPatched { + public PathAfterDbGitDumpsDbSchemaToGit( + CharSequence commitMessage, + CharSequence pushRemoteName, + CharSequence gitUrl, + ArgsDbGitLink dbLinkArgs, + ArgsDbGitAddRemote addRemoteArgs, + CharSequence ignoreChars, + Patch checkoutPatch, + PrintStream printStream, + Path workingDirectory + ) { + super( + new PatchSequential<>( + checkoutPatch, + new PathPatchDbGitLink(dbLinkArgs, printStream), + new PathPatchCreatingFile(".dbgit/.dbignore", ignoreChars), + new PathPatchRunningDbGit(new ArgsExplicit("add", "\"*\"", "-v"), printStream), + new PathPatchRunningDbGit(new ArgsExplicit("commit", "-m", commitMessage), printStream), + new PathPatchRunningDbGit(new ArgsExplicit("push", pushRemoteName),printStream) + ), + new PathWithDbGitRepoCloned(gitUrl, addRemoteArgs, printStream, workingDirectory) + ); + } + +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitLinkAndAdd.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitLinkAndAdd.java new file mode 100644 index 0000000..36632f2 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathAfterDbGitLinkAndAdd.java @@ -0,0 +1,27 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.scenarios; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchCreatingFile; +import ru.fusionsoft.dbgit.integration.primitives.path.PathWithFiles; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.specific.ArgsDbGitLink; +import ru.fusionsoft.dbgit.integration.primitives.path.PathAfterDbGitRun; + +public class PathAfterDbGitLinkAndAdd extends PathAfterDbGitRun { + public PathAfterDbGitLinkAndAdd(ArgsDbGitLink argsDbGitLink, CharSequence ignoreChars, PrintStream printStream, Path origin) { + super( + new ArgsExplicit("add", "\"*\"", "-v"), + printStream, + new PathWithFiles( + new PathPatchCreatingFile(".dbgit/.dbignore", ignoreChars), + new PathAfterDbGitRun(argsDbGitLink, printStream, origin) + ) + ); + } + + public PathAfterDbGitLinkAndAdd(ArgsDbGitLink argsDbGitLink, CharSequence ignoreChars, Path origin) { + this(argsDbGitLink, ignoreChars, new DefaultPrintStream(), origin); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathWithBuildingDbGitExecutableFromGit.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathWithBuildingDbGitExecutableFromGit.java new file mode 100644 index 0000000..ce96dfc --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/path/specific/dbgit/scenarios/PathWithBuildingDbGitExecutableFromGit.java @@ -0,0 +1,64 @@ +package ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.scenarios; + +import java.io.PrintStream; +import java.nio.file.Path; +import ru.fusionsoft.dbgit.integration.primitives.printstream.DefaultPrintStream; +import ru.fusionsoft.dbgit.integration.primitives.PatchSequential; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsExplicit; +import ru.fusionsoft.dbgit.integration.primitives.args.ArgsWithPrepend; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchCloningGitRepo; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchDeletingFiles; +import ru.fusionsoft.dbgit.integration.primitives.patch.PathPatchDeletingFilesWildcard; +import ru.fusionsoft.dbgit.integration.primitives.path.PathAfterProcessRun; +import ru.fusionsoft.dbgit.integration.primitives.path.PathEnvelope; +import ru.fusionsoft.dbgit.integration.primitives.path.PathNotProjectRoot; +import ru.fusionsoft.dbgit.integration.primitives.path.specific.dbgit.PathOfBuiltDbGitExecutable; +import ru.fusionsoft.dbgit.integration.primitives.path.PathPatched; + +public class PathWithBuildingDbGitExecutableFromGit extends PathEnvelope { + + public PathWithBuildingDbGitExecutableFromGit(String commitHash, PrintStream printStream, Path origin) { + super(() -> { + + return new PathOfBuiltDbGitExecutable( + new PathAfterProcessRun( + new ArgsWithPrepend( + new ArgsExplicit( + "mvn", + "package", + "appassembler:assemble", + "-D", + "skipTests" + ), + new ArgsExplicit( + System.getenv("ComSpec"), + "/C" + ) + ), + printStream, + new PathPatched( + new PathNotProjectRoot(origin), + new PatchSequential<>( + new PathPatchDeletingFilesWildcard( + "*" + ), + new PathPatchCloningGitRepo( + "https://github.com/databasegit/dbgit.git", + commitHash, + printStream + ), + new PathPatchDeletingFiles( + "src/test/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssqlTest.java" + ) + ) + ) + ) + ); + + }); + } + + public PathWithBuildingDbGitExecutableFromGit(String commitHash, Path origin) { + this(commitHash, new DefaultPrintStream(), origin); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/DefaultPrintStream.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/DefaultPrintStream.java new file mode 100644 index 0000000..288b0eb --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/DefaultPrintStream.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.printstream; + +import java.io.PrintStream; + +public class DefaultPrintStream extends PrintStream { + public DefaultPrintStream() { + super(new PrintStreamToConsole()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/OutputStreamToConsole.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/OutputStreamToConsole.java new file mode 100644 index 0000000..5719464 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/OutputStreamToConsole.java @@ -0,0 +1,10 @@ +package ru.fusionsoft.dbgit.integration.primitives.printstream; + +import java.io.OutputStream; + +public class OutputStreamToConsole extends OutputStream { + @Override + public final void write(int i) { + System.out.write(i); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/OutputStreamToNowhere.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/OutputStreamToNowhere.java new file mode 100644 index 0000000..dd8b931 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/OutputStreamToNowhere.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.printstream; + +import java.io.OutputStream; + +public class OutputStreamToNowhere extends OutputStream { + @Override + public void write(int b) { + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/PrintStreamToConsole.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/PrintStreamToConsole.java new file mode 100644 index 0000000..d06d72d --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/PrintStreamToConsole.java @@ -0,0 +1,9 @@ +package ru.fusionsoft.dbgit.integration.primitives.printstream; + +import java.io.PrintStream; + +public class PrintStreamToConsole extends PrintStream { + public PrintStreamToConsole() { + super(new OutputStreamToConsole()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/PrintStreamToNowhere.java b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/PrintStreamToNowhere.java new file mode 100644 index 0000000..ae5f3c3 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/integration/primitives/printstream/PrintStreamToNowhere.java @@ -0,0 +1,10 @@ +package ru.fusionsoft.dbgit.integration.primitives.printstream; + +import java.io.PrintStream; + +public class PrintStreamToNowhere extends PrintStream { + + public PrintStreamToNowhere() { + super(new OutputStreamToNowhere()); + } +} diff --git a/src/test/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssqlTest.java b/src/test/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssqlTest.java index 4831bd7..2db84ff 100644 --- a/src/test/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssqlTest.java +++ b/src/test/java/ru/fusionsoft/dbgit/mssql/DBAdapterMssqlTest.java @@ -3,28 +3,23 @@ import com.google.common.collect.Lists; import org.apache.commons.lang3.time.StopWatch; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import ru.fusionsoft.dbgit.adapters.AdapterFactory; -import ru.fusionsoft.dbgit.adapters.IFactoryDBConvertAdapter; import ru.fusionsoft.dbgit.core.DBGitConfig; import ru.fusionsoft.dbgit.core.db.DbType; import ru.fusionsoft.dbgit.dbobjects.*; import ru.fusionsoft.dbgit.meta.*; -import ru.fusionsoft.dbgit.oracle.DBRestorePackageOracle; import ru.fusionsoft.dbgit.statement.StatementLogging; import ru.fusionsoft.dbgit.utils.ConsoleWriter; -import javax.naming.Name; import java.sql.*; import java.text.MessageFormat; import java.util.*; - -import static org.junit.Assert.*; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; +@Tag("mssqlTest") +@Tag("deprecated") public class DBAdapterMssqlTest { public static Properties testProps; @@ -37,13 +32,13 @@ public class DBAdapterMssqlTest { * Setup of ip an ports via SQLServerManager11.msc also needed, mine was: * Protocols -> SQL EXPRESS protocols -> Protocol -> Listen all to true and * Protocols -> SQL EXPRESS protocols -> Protocol -> IP adresses -> IPAll -> TCP Port to 1433 and Dynamic TCP Port to blank - * */ + */ - public static String TEST_CONN_URL = "localhost:1433"; - public static String TEST_CONN_CATALOG = "MyDiet"; + public static String TEST_CONN_URL = "23.105.226.179:1433"; + public static String TEST_CONN_CATALOG = "testdatabasegit"; public static String TEST_CONN_STRING = "jdbc:sqlserver://"+TEST_CONN_URL+";databaseName="+TEST_CONN_CATALOG+";integratedSecurity=false;"; - public static String TEST_CONN_USER = "test"; - public static String TEST_CONN_PASS = "test"; + public static String TEST_CONN_USER = "sa"; + public static String TEST_CONN_PASS = "s%G351as"; private static DBAdapterMssql testAdapter; private static DBBackupAdapterMssql testBackup; @@ -74,9 +69,10 @@ public class DBAdapterMssqlTest { private static String schema; private static String viewName = "TestView"; private static String sequenceName = "TestSequence"; + private static int messageLevel = 0; - @Before + @BeforeEach public void setUp() throws Exception { if(!isInitialized){ try { @@ -93,12 +89,13 @@ public void setUp() throws Exception { catch (Exception ex){ fail(ex.getMessage()); } - dropBackupTables(); + dropBackupObjects(); } } - @After - public void tearDown() throws Exception { + @AfterEach + public void tearDown() throws Exception + { } @Test @@ -189,7 +186,7 @@ public void getTableFields() throws Exception{ Map fields = testAdapter.getTableFields(schema, name); assertEquals("sql_variant(0)", fields.get("col10").getTypeSQL()); - assertEquals("native", fields.get("col10").getTypeUniversal()); + assertEquals("native",fields.get("col10").getTypeUniversal().toString()); dropTable(schema + "." + name); } @@ -208,7 +205,7 @@ public void getTableData() { createTestTriggerProcedureFunctions(triggerTableName); DBTableData data = testAdapter.getTableData(testConnection.getSchema(), triggerTableName); - ResultSet rs = data.getResultSet(); + ResultSet rs = data.resultSet(); ResultSetMetaData md = rs.getMetaData(); int cols = md.getColumnCount(); rs.next(); @@ -222,7 +219,7 @@ public void getTableData() { System.out.println(watch.toString()); } catch (Exception ex) { - fail(ex.toString()); + fail(ex.getLocalizedMessage()); } } @@ -238,7 +235,7 @@ public void getTableDataPortion() { ); DBTableData data = testAdapter.getTableDataPortion("tempdb.", "#bigDummyTable", 2, 0); - ResultSet rs = data.getResultSet(); + ResultSet rs = data.resultSet(); while (rs.next()) rowsAffected++; @@ -628,6 +625,7 @@ public void backupMetaTable() throws Exception{ @Test public void backupMetaSql() throws Exception{ + dropBackupObjects(); createTestTriggerProcedureFunctions(triggerTableName); createTestView(schema, viewName); @@ -920,15 +918,52 @@ public void restoreTriggerAfterDrop() throws Exception { //heplers - public void dropBackupTables() throws Exception{ + public void dropBackupObjects() throws Exception{ Map tables = testAdapter.getTables(schema); for (DBTable table : tables.values()){ if(table.getName().startsWith("BACKUP$")){ + ConsoleWriter.println("drop "+table.getName(), messageLevel); dropTable(schema+"."+table.getName()); } } + + Map views = testAdapter.getViews(schema); + for (DBView view : views.values()){ + if(view.getName().startsWith("BACKUP$")){ + ConsoleWriter.println("drop "+view.getName(), messageLevel); + dropView(schema+"."+view.getName()); + } + } + + Map Triggers = testAdapter.getTriggers(schema); + for (DBTrigger Trigger : Triggers.values()){ + if(Trigger.getName().startsWith("BACKUP$")){ + ConsoleWriter.println("drop "+Trigger.getName(), messageLevel); + dropTrigger(schema+"."+Trigger.getName()); + } + } + + Map Procedures = testAdapter.getProcedures(schema); + for (DBProcedure Procedure : Procedures.values()){ + if(Procedure.getName().startsWith("BACKUP$")){ + ConsoleWriter.println("drop "+Procedure.getName(), messageLevel); + dropProcedure(schema+"."+Procedure.getName()); + } + } + + Map Functions = testAdapter.getFunctions(schema); + for (DBFunction Function : Functions.values()){ + if(Function.getName().startsWith("BACKUP$")){ + ConsoleWriter.println("drop "+Function.getName(), messageLevel); + dropFunction(schema+"."+Function.getName()); + } + } + + } + + public boolean trySetMasterCatalog(){ try { if (!isMasterDatabase) { @@ -1077,6 +1112,42 @@ public void dropTable(String schemaAndName) throws Exception{ stmt.close(); } + public void dropView(String schemaAndName) throws Exception{ + Statement stmt = testConnection.createStatement(); + String name = convertSchemaAndName(schemaAndName); + String ddl = MessageFormat.format("IF OBJECT_ID(''{0}'', ''V'') IS NOT NULL DROP VIEW {0}", name); + stmt.execute(ddl); + stmt.close(); + } + + public void dropTrigger(String schemaAndName) throws Exception{ + Statement stmt = testConnection.createStatement(); + String name = convertSchemaAndName(schemaAndName); + String ddl = MessageFormat.format("IF OBJECT_ID(''{0}'', ''TR'') IS NOT NULL DROP TRIGGER {0}", name); + stmt.execute(ddl); + stmt.close(); + } + + public void dropProcedure(String schemaAndName) throws Exception{ + Statement stmt = testConnection.createStatement(); + String name = convertSchemaAndName(schemaAndName); + String ddl = MessageFormat.format("IF OBJECT_ID(''{0}'', ''P'') IS NOT NULL DROP PROCEDURE {0}", name); + stmt.execute(ddl); + stmt.close(); + } + + public void dropFunction(String schemaAndName) throws Exception{ + Statement stmt = testConnection.createStatement(); + String name = convertSchemaAndName(schemaAndName); + String ddl1 = MessageFormat.format("IF OBJECT_ID(''{0}'', ''FN'') IS NOT NULL DROP FUNCTION {0}", name); + String ddl2 = MessageFormat.format("IF OBJECT_ID(''{0}'', ''IF'') IS NOT NULL DROP FUNCTION {0}", name); + String ddl3 = MessageFormat.format("IF OBJECT_ID(''{0}'', ''TF'') IS NOT NULL DROP FUNCTION {0}", name); + stmt.execute(ddl1); + stmt.execute(ddl2); + stmt.execute(ddl3); + stmt.close(); + } + public String convertSchemaAndName(String san) { return san.startsWith("#") ? "tempdb.." + san.substring(1) @@ -1283,7 +1354,7 @@ public void dropBigDummyTable() throws Exception{ Statement stmt = testConnection.createStatement(); try { stmt.execute("DROP TABLE tempdb..#bigDummyTable\n"); } catch (SQLException ex) { - ConsoleWriter.println("Failed to drop #bigDummyTable"); + ConsoleWriter.println("Failed to drop #bigDummyTable", messageLevel); } stmt.close(); } @@ -1450,4 +1521,4 @@ private void dropTestTriggerProcedureFunctions(String tableName) throws Exceptio ); stmt.close(); } -} \ No newline at end of file +} diff --git a/src/test/java/ru/fusionsoft/dbgit/utils/MaskFilterTest.java b/src/test/java/ru/fusionsoft/dbgit/utils/MaskFilterTest.java new file mode 100644 index 0000000..3a7b090 --- /dev/null +++ b/src/test/java/ru/fusionsoft/dbgit/utils/MaskFilterTest.java @@ -0,0 +1,29 @@ +package ru.fusionsoft.dbgit.utils; + +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + +public class MaskFilterTest { + + @Test + public void match() { + MaskFilter mf = new MaskFilter("pub*.*"); + + String textTbl = "public/ad_group_roles.tbl"; + String textCsv = "public/ad_group_roles.csv"; + + assertTrue(mf.match(textTbl)); + assertTrue(mf.match(textCsv)); + } + + @Test + public void matchExtention() { + MaskFilter mfCsv = new MaskFilter("pub*lic*.csv"); + + String textTbl = "public/ad_group_roles.tbl"; + String textCsv = "public/ad_group_roles.csv"; + + assertFalse(mfCsv.match(textTbl)); + assertTrue(mfCsv.match(textCsv)); + } +} \ No newline at end of file diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..61d5b6b --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + .dbgit/logs + + + + + + + + + ${log_dir_rep}/log-${time}.log + + + ${log_dir_home}/log-${time}.log + + + + + %date %level [%thread] %logger{10} [%file:%line] %msg%n + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + --> + + + + \ No newline at end of file