Skip to content

Commit f476258

Browse files
committed
scheme2ddl-44 CREATE (UNIQUE) INDEX statement in table files are not sorted
- add new method `sortIndexesInDDL` in DDLFormatter class - add new parameter of DDLFormatter `sortCreateIndexStatements` with default value true added - invoke `sortIndexesInDDL` in UserObjectProcessor
1 parent 92a2fc9 commit f476258

File tree

4 files changed

+127
-44
lines changed

4 files changed

+127
-44
lines changed

src/main/java/com/googlecode/scheme2ddl/DDLFormatter.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.googlecode.scheme2ddl;
22

3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
36
import java.util.regex.Matcher;
47
import java.util.regex.Pattern;
58

@@ -10,6 +13,7 @@
1013
public class DDLFormatter {
1114

1215
private boolean noFormat;
16+
private boolean sortCreateIndexStatements = true;
1317
private boolean statementOnNewLine;
1418
private boolean isMorePrettyFormat = false;
1519

@@ -49,6 +53,9 @@ public void setIsMorePrettyFormat(boolean isMorePrettyFormat) {
4953
this.isMorePrettyFormat = isMorePrettyFormat;
5054
}
5155

56+
public void setSortCreateIndexStatements(boolean sortCreateIndexStatements) {
57+
this.sortCreateIndexStatements = sortCreateIndexStatements;
58+
}
5259

5360
public String replaceActualSequenceValueWithOne(String res) {
5461

@@ -65,4 +72,31 @@ public String replaceActualSequenceValueWithOne(String res) {
6572
}
6673
return output;
6774
}
75+
76+
/**
77+
* Read input string with list of 'create index' statements and, tokenize and sort alphabetically.
78+
* @param dependentDLL -string with list of 'create index' statements
79+
* @return string with sorted alphabetically 'create index' statements
80+
*/
81+
public String sortIndexesInDDL(String dependentDLL) {
82+
if (noFormat || !sortCreateIndexStatements){
83+
return dependentDLL;
84+
}
85+
String[] parts = dependentDLL.split("(?=CREATE INDEX)|(?=CREATE UNIQUE INDEX)|(?=CREATE BITMAP INDEX)");
86+
List<String> list = new ArrayList<String>();
87+
for (String part : parts) {
88+
if (part != null && !part.trim().isEmpty()) {
89+
list.add(part.trim());
90+
}
91+
}
92+
Collections.sort(list);
93+
StringBuilder s = new StringBuilder();
94+
String prefix = "\n "; //to preserve formatting of dbms_metadata.get_depended_ddl output
95+
for (String statement:list){
96+
s.append(prefix);
97+
prefix = "\n";
98+
s.append(statement);
99+
}
100+
return s.toString();
101+
}
68102
}

src/main/java/com/googlecode/scheme2ddl/UserObjectProcessor.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,21 @@ private String map2Ddl(UserObject userObject) throws CannotGetDDLException, NonS
7575
if (userObject.getType().equals("REFRESH_GROUP")) {
7676
return ddlFormatter.formatDDL(userObjectDao.findRefGroupDDL(userObject.getType(), userObject.getName()));
7777
}
78-
String res = userObjectDao.findPrimaryDDL(map2TypeForDBMS(userObject.getType()), userObject.getName());
78+
StringBuilder res = new StringBuilder(userObjectDao.findPrimaryDDL(map2TypeForDBMS(userObject.getType()), userObject.getName()));
7979
if (userObject.getType().equals("SEQUENCE") && replaceSequenceValues) {
80-
res = ddlFormatter.replaceActualSequenceValueWithOne(res);
80+
res = new StringBuilder(ddlFormatter.replaceActualSequenceValueWithOne(res.toString()));
8181
}
8282
Set<String> dependedTypes = dependencies.get(userObject.getType());
8383
if (dependedTypes != null) {
8484
for (String dependedType : dependedTypes) {
85-
res += userObjectDao.findDependentDLLByTypeName(dependedType, userObject.getName());
85+
String dependentDLL = userObjectDao.findDependentDLLByTypeName(dependedType, userObject.getName());
86+
if (dependedType.equals("INDEX")){
87+
dependentDLL = ddlFormatter.sortIndexesInDDL(dependentDLL);
88+
}
89+
res.append(dependentDLL);
8690
}
8791
}
88-
return ddlFormatter.formatDDL(res);
92+
return ddlFormatter.formatDDL(res.toString());
8993
} catch (Exception e) {
9094
log.warn(String.format("Cannot get DDL for object %s with error message %s", userObject, e.getMessage()));
9195
if (stopOnWarning) {

src/main/resources/scheme2ddl.config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<!-- Check it to true if you don't want apply formatting on DMBS_OUTPUT. -->
5353
<property name="noFormat" value="false"/>
5454
<property name="isMorePrettyFormat" value="false"/>
55+
<property name="sortCreateIndexStatements" value="true"/>
5556
</bean>
5657

5758
<!-- rules for construct filenames -->
Lines changed: 84 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,85 @@
1-
package com.googlecode.scheme2ddl;
2-
3-
4-
import org.testng.annotations.Test;
5-
6-
import static org.testng.Assert.assertNotEquals;
7-
import static org.testng.AssertJUnit.assertEquals;
8-
9-
10-
/**
11-
* @author ar
12-
* @since Date: 18.04.2015
13-
*/
14-
public class DDLFormatterTest {
15-
16-
private DDLFormatter ddlFormatter = new DDLFormatter();
17-
18-
@Test
19-
public void testReplaceActualSequenceValueWithOne() throws Exception {
20-
21-
String s = "CREATE SEQUENCE \"TEST01\".\"SEQ_01\" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 2122 CACHE 20 NOORDER NOCYCLE ;\n";
22-
String res = ddlFormatter.replaceActualSequenceValueWithOne(s);
23-
assertEquals(
24-
"CREATE SEQUENCE \"TEST01\".\"SEQ_01\" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE ;\n" +
25-
"\r\n" +
26-
"/* -- actual sequence value was replaced by scheme2ddl to 1 */"
27-
, res);
28-
29-
}
30-
31-
@Test
32-
public void testReplaceActualSequenceValueWithOneOnWrongDDL() throws Exception {
33-
34-
String s = "CREATE TABLE \"TEST01\".\"SEQ_01\" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 2122 CACHE 20 NOORDER NOCYCLE ;\n";
35-
String res = ddlFormatter.replaceActualSequenceValueWithOne(s);
36-
assertNotEquals(
37-
"CREATE TABLE \"TEST01\".\"SEQ_01\" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE ;\n"
38-
, res);
39-
40-
}
1+
package com.googlecode.scheme2ddl;
2+
3+
4+
import org.testng.annotations.Test;
5+
6+
import static org.testng.Assert.assertNotEquals;
7+
import static org.testng.AssertJUnit.assertEquals;
8+
9+
10+
/**
11+
* @author ar
12+
* @since Date: 18.04.2015
13+
*/
14+
public class DDLFormatterTest {
15+
16+
private DDLFormatter ddlFormatter = new DDLFormatter();
17+
18+
@Test
19+
public void testReplaceActualSequenceValueWithOne() throws Exception {
20+
21+
String s = "CREATE SEQUENCE \"TEST01\".\"SEQ_01\" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 2122 CACHE 20 NOORDER NOCYCLE ;\n";
22+
String res = ddlFormatter.replaceActualSequenceValueWithOne(s);
23+
assertEquals(
24+
"CREATE SEQUENCE \"TEST01\".\"SEQ_01\" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE ;\n" +
25+
"\r\n" +
26+
"/* -- actual sequence value was replaced by scheme2ddl to 1 */"
27+
, res);
28+
29+
}
30+
31+
@Test
32+
public void testReplaceActualSequenceValueWithOneOnWrongDDL() throws Exception {
33+
34+
String s = "CREATE TABLE \"TEST01\".\"SEQ_01\" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 2122 CACHE 20 NOORDER NOCYCLE ;\n";
35+
String res = ddlFormatter.replaceActualSequenceValueWithOne(s);
36+
assertNotEquals(
37+
"CREATE TABLE \"TEST01\".\"SEQ_01\" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE ;\n"
38+
, res);
39+
40+
}
41+
42+
43+
@Test
44+
public void testSortPreserveOriginalDDLIfNoSort() {
45+
String s = "\n CREATE UNIQUE INDEX \"HR\".\"REG_ID_PK\" ON \"HR\".\"REGIONS\" (\"REGION_ID\") \n" +
46+
" ;";
47+
String res = ddlFormatter.sortIndexesInDDL(s);
48+
assertEquals(s, res);
49+
}
50+
51+
@Test
52+
public void testSortIndexes() {
53+
String s = " CREATE INDEX \"HR\".\"A_IDX2\" ON \"HR\".\"A\" (\"C2\") \n" +
54+
" ;\n" +
55+
" CREATE INDEX \"HR\".\"A_IDX1\" ON \"HR\".\"A\" (\"C3\") \n" +
56+
" ;";
57+
String res = ddlFormatter.sortIndexesInDDL(s);
58+
assertEquals(
59+
"\n CREATE INDEX \"HR\".\"A_IDX1\" ON \"HR\".\"A\" (\"C3\") \n" +
60+
" ;\n" +
61+
"CREATE INDEX \"HR\".\"A_IDX2\" ON \"HR\".\"A\" (\"C2\") \n" +
62+
" ;"
63+
, res);
64+
}
65+
66+
@Test
67+
public void testSortIndexesUniq() {
68+
String s =
69+
" \n" +
70+
"CREATE UNIQUE INDEX \"HR\".\"A_UNIQ2\" ON \"HR\".\"A\" (\"C1\", \"B2\") \n" +
71+
" ;\n" +
72+
" CREATE INDEX \"HR\".\"A_IDX1\" ON \"HR\".\"A\" (\"C1\") \n" +
73+
" ; " +
74+
"CREATE BITMAP INDEX \"HR\".\"A_BITMAP_IDX\" ON \"HR\".\"A\" (\"C1\", \"C5\") \n" +
75+
" ;\n";
76+
String res = ddlFormatter.sortIndexesInDDL(s);
77+
assertEquals("\n " +
78+
"CREATE BITMAP INDEX \"HR\".\"A_BITMAP_IDX\" ON \"HR\".\"A\" (\"C1\", \"C5\") \n" +
79+
" ;\n" +
80+
"CREATE INDEX \"HR\".\"A_IDX1\" ON \"HR\".\"A\" (\"C1\") \n" +
81+
" ;\n" +
82+
"CREATE UNIQUE INDEX \"HR\".\"A_UNIQ2\" ON \"HR\".\"A\" (\"C1\", \"B2\") \n" +
83+
" ;", res);
84+
}
4185
}

0 commit comments

Comments
 (0)