88import ai .chat2db .spi .model .Table ;
99import ai .chat2db .spi .model .TableColumn ;
1010import ai .chat2db .spi .model .TableIndex ;
11+ import cn .hutool .core .util .ArrayUtil ;
1112import org .apache .commons .lang3 .StringUtils ;
1213
14+ import java .util .Arrays ;
15+ import java .util .HashMap ;
16+ import java .util .Map ;
17+
1318
1419public class MysqlSqlBuilder extends DefaultSqlBuilder implements SqlBuilder {
1520 @ Override
1621 public String buildCreateTableSql (Table table ) {
1722 StringBuilder script = new StringBuilder ();
1823 script .append ("CREATE TABLE " );
19- if (StringUtils .isNotBlank (table .getDatabaseName ())) {
24+ if (StringUtils .isNotBlank (table .getDatabaseName ())) {
2025 script .append ("`" ).append (table .getDatabaseName ()).append ("`" ).append ("." );
2126 }
2227 script .append ("`" ).append (table .getName ()).append ("`" ).append (" (" ).append ("\n " );
2328
2429 // append column
2530 for (TableColumn column : table .getColumnList ()) {
26- if (StringUtils .isBlank (column .getName ())|| StringUtils .isBlank (column .getColumnType ())){
31+ if (StringUtils .isBlank (column .getName ()) || StringUtils .isBlank (column .getColumnType ())) {
2732 continue ;
2833 }
2934 MysqlColumnTypeEnum typeEnum = MysqlColumnTypeEnum .getByType (column .getColumnType ());
@@ -32,7 +37,7 @@ public String buildCreateTableSql(Table table) {
3237
3338 // append primary key and index
3439 for (TableIndex tableIndex : table .getIndexList ()) {
35- if (StringUtils .isBlank (tableIndex .getName ())|| StringUtils .isBlank (tableIndex .getType ())){
40+ if (StringUtils .isBlank (tableIndex .getName ()) || StringUtils .isBlank (tableIndex .getType ())) {
3641 continue ;
3742 }
3843 MysqlIndexTypeEnum mysqlIndexTypeEnum = MysqlIndexTypeEnum .getByType (tableIndex .getType ());
@@ -75,7 +80,7 @@ public String buildCreateTableSql(Table table) {
7580 public String buildModifyTaleSql (Table oldTable , Table newTable ) {
7681 StringBuilder script = new StringBuilder ();
7782 script .append ("ALTER TABLE " );
78- if (StringUtils .isNotBlank (oldTable .getDatabaseName ())) {
83+ if (StringUtils .isNotBlank (oldTable .getDatabaseName ())) {
7984 script .append ("`" ).append (oldTable .getDatabaseName ()).append ("`" ).append ("." );
8085 }
8186 script .append ("`" ).append (oldTable .getName ()).append ("`" ).append ("\n " );
@@ -91,7 +96,7 @@ public String buildModifyTaleSql(Table oldTable, Table newTable) {
9196
9297 // append modify column
9398 for (TableColumn tableColumn : newTable .getColumnList ()) {
94- if (StringUtils .isNotBlank (tableColumn .getEditStatus ()) && StringUtils .isNotBlank (tableColumn .getColumnType ())&& StringUtils .isNotBlank (tableColumn .getName ())){
99+ if (StringUtils .isNotBlank (tableColumn .getEditStatus ()) && StringUtils .isNotBlank (tableColumn .getColumnType ()) && StringUtils .isNotBlank (tableColumn .getName ())) {
95100 MysqlColumnTypeEnum typeEnum = MysqlColumnTypeEnum .getByType (tableColumn .getColumnType ());
96101 script .append ("\t " ).append (typeEnum .buildModifyColumn (tableColumn )).append (",\n " );
97102 }
@@ -104,7 +109,11 @@ public String buildModifyTaleSql(Table oldTable, Table newTable) {
104109 script .append ("\t " ).append (mysqlIndexTypeEnum .buildModifyIndex (tableIndex )).append (",\n " );
105110 }
106111 }
107- if (script .length ()>2 ) {
112+
113+ // append reorder column
114+ script .append ("\t " ).append (buildGenerateReorderColumnSql (oldTable , newTable ));
115+
116+ if (script .length () > 2 ) {
108117 script = new StringBuilder (script .substring (0 , script .length () - 2 ));
109118 script .append (";" );
110119 }
@@ -113,7 +122,6 @@ public String buildModifyTaleSql(Table oldTable, Table newTable) {
113122 }
114123
115124
116-
117125 @ Override
118126 public String pageLimit (String sql , int offset , int pageNo , int pageSize ) {
119127 StringBuilder sqlBuilder = new StringBuilder (sql .length () + 14 );
@@ -131,12 +139,10 @@ public String pageLimit(String sql, int offset, int pageNo, int pageSize) {
131139 }
132140
133141
134-
135-
136142 @ Override
137143 public String buildCreateDatabaseSql (Database database ) {
138144 StringBuilder sqlBuilder = new StringBuilder ();
139- sqlBuilder .append ("CREATE DATABASE `" + database .getName ()+ "`" );
145+ sqlBuilder .append ("CREATE DATABASE `" + database .getName () + "`" );
140146 if (StringUtils .isNotBlank (database .getCharset ())) {
141147 sqlBuilder .append (" DEFAULT CHARACTER SET=" ).append (database .getCharset ());
142148 }
@@ -146,4 +152,142 @@ public String buildCreateDatabaseSql(Database database) {
146152 return sqlBuilder .toString ();
147153 }
148154
155+ public String buildGenerateReorderColumnSql (Table oldTable , Table newTable ) {
156+ StringBuilder sql = new StringBuilder ();
157+ int n = 0 ;
158+ // Create a map to store the index of each column in the old table's column list
159+ Map <String , Integer > oldColumnIndexMap = new HashMap <>();
160+ for (int i = 0 ; i < oldTable .getColumnList ().size (); i ++) {
161+ oldColumnIndexMap .put (oldTable .getColumnList ().get (i ).getName (), i );
162+ }
163+ String [] oldColumnArray = oldTable .getColumnList ().stream ().map (TableColumn ::getName ).toArray (String []::new );
164+ String [] newColumnArray = newTable .getColumnList ().stream ().map (TableColumn ::getName ).toArray (String []::new );
165+
166+ buildSql (oldColumnArray , newColumnArray , sql , oldTable , newTable , n );
167+
168+ return sql .toString ();
169+ }
170+
171+ private String [] buildSql (String [] originalArray , String [] targetArray , StringBuilder sql , Table oldTable , Table newTable , int n ) {
172+ // 先完成首位移动
173+ if (!originalArray [0 ].equals (targetArray [0 ])) {
174+ int a = findIndex (originalArray , targetArray [0 ]);
175+ TableColumn column = oldTable .getColumnList ().stream ().filter (col -> StringUtils .equals (col .getName (), originalArray [a ])).findFirst ().get ();
176+ String [] newArray = moveElement (originalArray , a , 0 );
177+ System .out .println (ArrayUtil .toString (newArray ));
178+ sql .append (" MODIFY COLUMN " );
179+ MysqlColumnTypeEnum typeEnum = MysqlColumnTypeEnum .getByType (column .getColumnType ());
180+ sql .append (typeEnum .buildColumn (column ));
181+ sql .append (" FIRST;\n " );
182+ n ++;
183+ if (Arrays .equals (newArray , targetArray )) {
184+ return newArray ;
185+ }
186+ String [] resultArray = buildSql (newArray , targetArray , sql , oldTable , newTable , n );
187+ if (Arrays .equals (resultArray , targetArray )) {
188+ return resultArray ;
189+ }
190+ }
191+
192+ // 在完成最后一位移动
193+ int max = originalArray .length - 1 ;
194+ if (!originalArray [max ].equals (targetArray [max ])) {
195+ int a = findIndex (originalArray , targetArray [max ]);
196+ //System.out.println("Move " + originalArray[a] + " after " + (a > 0 ? originalArray[max] : "start"));
197+ TableColumn column = oldTable .getColumnList ().stream ().filter (col -> StringUtils .equals (col .getName (), originalArray [a ])).findFirst ().get ();
198+ String [] newArray = moveElement (originalArray , a , max );
199+ System .out .println (ArrayUtil .toString (newArray ));
200+ if (n > 0 ) {
201+ sql .append ("ALTER TABLE " );
202+ if (StringUtils .isNotBlank (oldTable .getDatabaseName ())) {
203+ sql .append ("`" ).append (oldTable .getDatabaseName ()).append ("`" ).append ("." );
204+ }
205+ sql .append ("`" ).append (oldTable .getName ()).append ("`" ).append ("\n " );
206+ }
207+ sql .append (" MODIFY COLUMN " );
208+ MysqlColumnTypeEnum typeEnum = MysqlColumnTypeEnum .getByType (column .getColumnType ());
209+ sql .append (typeEnum .buildColumn (column ));
210+ sql .append (" " );
211+ sql .append (" AFTER " );
212+ sql .append (oldTable .getColumnList ().get (max ).getName ());
213+ sql .append (";\n " );
214+ n ++;
215+ if (Arrays .equals (newArray , targetArray )) {
216+ return newArray ;
217+ }
218+ String [] resultArray = buildSql (newArray , targetArray , sql , oldTable , newTable , n );
219+ if (Arrays .equals (resultArray , targetArray )) {
220+ return resultArray ;
221+ }
222+ }
223+
224+
225+ for (int i = 0 ; i < originalArray .length ; i ++) {
226+ int a = findIndex (targetArray , originalArray [i ]);
227+ if (i != a && isMoveValid (originalArray , targetArray , i , a )) {
228+ // oldTable.getColumnList中查找name为a
229+ int finalI = i ;
230+ TableColumn column = oldTable .getColumnList ().stream ().filter (col -> StringUtils .equals (col .getName (), originalArray [finalI ])).findFirst ().get ();
231+ if (n > 0 ) {
232+ sql .append ("ALTER TABLE " );
233+ if (StringUtils .isNotBlank (oldTable .getDatabaseName ())) {
234+ sql .append ("`" ).append (oldTable .getDatabaseName ()).append ("`" ).append ("." );
235+ }
236+ sql .append ("`" ).append (oldTable .getName ()).append ("`" ).append ("\n " );
237+ }
238+ sql .append (" MODIFY COLUMN " );
239+ MysqlColumnTypeEnum typeEnum = MysqlColumnTypeEnum .getByType (column .getColumnType ());
240+ sql .append (typeEnum .buildColumn (column ));
241+ sql .append (" " );
242+ sql .append (" AFTER " );
243+ if (i < a ) {
244+ sql .append (originalArray [a ]);
245+ } else {
246+ sql .append (originalArray [a - 1 ]);
247+ }
248+
249+ sql .append (";\n " );
250+ n ++;
251+ String [] newArray = moveElement (originalArray , i , a );
252+ if (Arrays .equals (newArray , targetArray )) {
253+ return newArray ;
254+ }
255+ String [] resultArray = buildSql (newArray , targetArray , sql , oldTable , newTable , n );
256+ if (Arrays .equals (resultArray , targetArray )) {
257+ return resultArray ;
258+ }
259+ }
260+ }
261+ return null ;
262+ }
263+
264+ private static int findIndex (String [] array , String element ) {
265+ for (int i = 0 ; i < array .length ; i ++) {
266+ if (array [i ].equals (element )) {
267+ return i ;
268+ }
269+ }
270+ return -1 ;
271+ }
272+
273+ private static boolean isMoveValid (String [] originalArray , String [] targetArray , int i , int a ) {
274+ System .out .println ("i : " + i + " a:" + a );
275+ return (i == 0 || a == 0 || !originalArray [i - 1 ].equals (targetArray [a - 1 ])) &&
276+ (i >= originalArray .length - 1 || a >= targetArray .length - 1 || !originalArray [i + 1 ].equals (targetArray [a + 1 ]));
277+ }
278+
279+ private static String [] moveElement (String [] originalArray , int from , int to ) {
280+ String [] newArray = new String [originalArray .length ];
281+ System .arraycopy (originalArray , 0 , newArray , 0 , originalArray .length );
282+ String temp = newArray [from ];
283+ if (from < to ) {
284+ System .arraycopy (originalArray , from + 1 , newArray , from , to - from );
285+ } else {
286+ System .arraycopy (originalArray , to , newArray , to + 1 , from - to );
287+ }
288+ newArray [to ] = temp ;
289+ System .out .println (ArrayUtil .toString (newArray ));
290+ return newArray ;
291+ }
292+
149293}
0 commit comments