|
1 | 1 | package org.ngbsn.generator; |
2 | 2 |
|
3 | | - |
4 | 3 | import net.sf.jsqlparser.parser.CCJSqlParserUtil; |
5 | 4 | import net.sf.jsqlparser.statement.Statements; |
6 | 5 | import net.sf.jsqlparser.statement.create.table.CreateTable; |
| 6 | +import net.sf.jsqlparser.statement.create.table.ForeignKeyIndex; |
7 | 7 | import net.sf.jsqlparser.statement.create.table.Index; |
8 | 8 | import org.apache.commons.text.CaseUtils; |
9 | 9 | import org.ngbsn.model.Column; |
| 10 | +import org.ngbsn.model.ForeignKeyConstraint; |
10 | 11 | import org.ngbsn.model.Table; |
| 12 | +import org.ngbsn.model.annotations.entityAnnotations.EntityAnnotation; |
| 13 | +import org.ngbsn.model.annotations.entityAnnotations.TableAnnotation; |
| 14 | +import org.ngbsn.model.annotations.fieldAnnotations.ColumnAnnotation; |
| 15 | +import org.ngbsn.model.annotations.fieldAnnotations.NotNullAnnotation; |
11 | 16 | import org.ngbsn.util.SQLToJavaMapping; |
12 | 17 | import org.slf4j.Logger; |
13 | 18 | import org.slf4j.LoggerFactory; |
14 | 19 |
|
15 | | -import java.util.ArrayList; |
16 | | -import java.util.List; |
17 | | -import java.util.Optional; |
| 20 | +import java.util.*; |
| 21 | + |
| 22 | +import static org.ngbsn.generator.AssociationMappingsGenerator.generateMappings; |
18 | 23 |
|
| 24 | +/** |
| 25 | + * Ignoring these annotations as they are useful only in DDL generation: |
| 26 | + * UNIQUE |
| 27 | + */ |
19 | 28 | public class ModelGenerator { |
20 | 29 | private static final Logger logger = LoggerFactory.getLogger(ModelGenerator.class); |
| 30 | + protected static Map<String, Table> tablesMap = new HashMap<>(); |
21 | 31 |
|
22 | 32 | public static List<Table> parse(final String sqlScript) { |
23 | 33 | try { |
24 | 34 | Statements statements = CCJSqlParserUtil.parseStatements(sqlScript); |
25 | | - List<Table> tables = new ArrayList<>(); |
26 | 35 | statements.getStatements().forEach(statement -> { |
| 36 | + //Iterating over all Tables |
27 | 37 | if (statement instanceof CreateTable parsedTable) { |
28 | 38 | Table table = new Table(); |
29 | | - tables.add(table); |
| 39 | + tablesMap.put(parsedTable.getTable().getName(), table); |
30 | 40 | table.setName(parsedTable.getTable().getName()); |
31 | 41 | table.setClassName(CaseUtils.toCamelCase(table.getName(), true, '_')); |
| 42 | + |
| 43 | + List<String> tableAnnotations = new ArrayList<>(); |
| 44 | + table.setAnnotations(tableAnnotations); |
| 45 | + //Adding @Entity |
| 46 | + tableAnnotations.add(new EntityAnnotation().toString()); |
| 47 | + //Adding @Table |
| 48 | + tableAnnotations.add(TableAnnotation.builder().tableName(parsedTable.getTable().getName()).build().toString()); |
| 49 | + |
32 | 50 | List<Column> columns = new ArrayList<>(); |
33 | | - parsedTable.getColumnDefinitions().forEach(columnDefinition -> { |
34 | | - Column column = new Column(); |
35 | | - columns.add(column); |
36 | | - column.setName(columnDefinition.getColumnName()); |
37 | | - column.setFieldName(CaseUtils.toCamelCase(column.getName(), false, '_')); |
38 | | - column.setType(SQLToJavaMapping.sqlToJavaMap.get(columnDefinition.getColDataType().getDataType())); |
39 | | - column.setNullable(true); |
40 | | - if (columnDefinition.getColumnSpecs() != null) { |
41 | | - String constraints = String.join(" ", columnDefinition.getColumnSpecs()); |
42 | | - if (constraints.contains("UNIQUE")) { |
43 | | - column.setUnique(true); |
44 | | - } |
45 | | - if (constraints.contains("NOT NULL")) { |
46 | | - column.setNullable(false); |
47 | | - } |
48 | | - } |
49 | | - }); |
50 | 51 | table.setColumns(columns); |
51 | | - Optional<Index> optionalIndex = parsedTable.getIndexes().stream().filter(index -> index.getType().equals("PRIMARY KEY")).findFirst(); |
52 | | - List<Index.ColumnParams> columnParamsList; |
53 | | - columnParamsList = optionalIndex.map(Index::getColumns).orElse(null); |
54 | | - if(columnParamsList != null){ |
55 | | - if(columnParamsList.size() > 1){ |
56 | | - table.setNumOfPrimaryKeyColumns(columnParamsList.size()); |
57 | | - } |
58 | | - List<Column> primaryKeyColumns = table.getColumns().stream().filter(column -> columnParamsList.stream().anyMatch(columnParams -> columnParams.getColumnName().equals(column.getName()))).toList(); |
59 | | - primaryKeyColumns.forEach(column -> column.setPrimaryKey(true)); |
60 | | - } |
| 52 | + extractColumns(parsedTable, columns); |
| 53 | + |
| 54 | + extractPrimaryKeys(parsedTable, table); |
| 55 | + |
| 56 | + extractForeignKeys(parsedTable, table); |
| 57 | + |
| 58 | + generateMappings(table); |
| 59 | + |
61 | 60 | } |
62 | 61 | }); |
63 | | - |
64 | | - return tables; |
| 62 | + return tablesMap.values().stream().toList(); |
65 | 63 | } catch (Exception e) { |
66 | | - logger.error(e.getMessage()); |
| 64 | + logger.error("Error occurred", e); |
67 | 65 | } |
68 | 66 | return null; |
69 | 67 | } |
| 68 | + |
| 69 | + /** |
| 70 | + * Looking for all foreign keys in this table and adding it to our model |
| 71 | + * |
| 72 | + * @param parsedTable The SQL script parsed table |
| 73 | + * @param table Table model |
| 74 | + */ |
| 75 | + private static void extractForeignKeys(CreateTable parsedTable, Table table) { |
| 76 | + List<Index> foreignKeyIndexes = parsedTable.getIndexes().stream().filter(index -> index instanceof ForeignKeyIndex).toList(); |
| 77 | + if (!foreignKeyIndexes.isEmpty()) { |
| 78 | + foreignKeyIndexes.forEach(index -> { |
| 79 | + if (index instanceof ForeignKeyIndex foreignKeyIndex) { |
| 80 | + ForeignKeyConstraint foreignKeyConstraint = new ForeignKeyConstraint(); |
| 81 | + foreignKeyConstraint.setColumns(foreignKeyIndex.getColumnsNames()); |
| 82 | + foreignKeyConstraint.setReferencedColumns(foreignKeyIndex.getReferencedColumnNames()); |
| 83 | + foreignKeyConstraint.setReferencedTableName(foreignKeyIndex.getTable().getName()); |
| 84 | + table.getForeignKeyConstraints().add(foreignKeyConstraint); |
| 85 | + } |
| 86 | + }); |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + /** |
| 91 | + * Looking for all primary keys in this table |
| 92 | + * |
| 93 | + * @param parsedTable The SQL script parsed table |
| 94 | + * @param table Table model |
| 95 | + */ |
| 96 | + private static void extractPrimaryKeys(CreateTable parsedTable, Table table) { |
| 97 | + Optional<Index> optionalIndex = parsedTable.getIndexes().stream().filter(index -> index.getType().equals("PRIMARY KEY")).findFirst(); |
| 98 | + List<Index.ColumnParams> columnParamsList = optionalIndex.map(Index::getColumns).orElse(null); |
| 99 | + if (columnParamsList != null) { |
| 100 | + if (columnParamsList.size() > 1) { |
| 101 | + table.setNumOfPrimaryKeyColumns(columnParamsList.size()); |
| 102 | + } |
| 103 | + List<Column> primaryKeyColumns = table.getColumns().stream(). |
| 104 | + filter(column -> columnParamsList.stream().anyMatch(columnParams -> columnParams.getColumnName().equals(column.getName()))).toList(); |
| 105 | + primaryKeyColumns.forEach(column -> column.setPrimaryKey(true)); |
| 106 | + } |
| 107 | + } |
| 108 | + |
| 109 | + /** |
| 110 | + * Generate column models for all the parsed table |
| 111 | + * |
| 112 | + * @param parsedTable Parsed table |
| 113 | + * @param columns List of generated column models |
| 114 | + */ |
| 115 | + private static void extractColumns(CreateTable parsedTable, List<Column> columns) { |
| 116 | + parsedTable.getColumnDefinitions().forEach(columnDefinition -> { |
| 117 | + Column column = new Column(); |
| 118 | + columns.add(column); |
| 119 | + List<String> columnAnnotations = new ArrayList<>(); |
| 120 | + column.setAnnotations(columnAnnotations); |
| 121 | + column.setName(columnDefinition.getColumnName()); |
| 122 | + //Adding @Column |
| 123 | + columnAnnotations.add(ColumnAnnotation.builder().columnName(column.getName()).build().toString()); |
| 124 | + column.setFieldName(CaseUtils.toCamelCase(columnDefinition.getColumnName(), false, '_')); |
| 125 | + column.setType(SQLToJavaMapping.sqlToJavaMap.get(columnDefinition.getColDataType().getDataType())); |
| 126 | + |
| 127 | + //Check for NOT NULL |
| 128 | + if (columnDefinition.getColumnSpecs() != null) { |
| 129 | + String constraints = String.join(" ", columnDefinition.getColumnSpecs()); |
| 130 | + if (constraints.contains("NOT NULL")) { |
| 131 | + columnAnnotations.add(NotNullAnnotation.builder().build().toString()); |
| 132 | + } |
| 133 | + } |
| 134 | + }); |
| 135 | + } |
70 | 136 | } |
0 commit comments