mirror of
				https://github.com/vran-dev/databasir.git
				synced 2025-10-31 04:29:20 +08:00 
			
		
		
		
	feature: code redesign
This commit is contained in:
		
							
								
								
									
										62
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								README.md
									
									
									
									
									
								
							| @@ -10,30 +10,23 @@ you could use `databasir` to generate database meta model, or render it as markd | |||||||
|  |  | ||||||
| ```java | ```java | ||||||
| java.sql.Connection connection=...; | java.sql.Connection connection=...; | ||||||
| DatabaseDocConfig config = DatabaseDocConfig.builder() |         DatabaseMeta meta=Databasir.of().get(connection,"user").orElseThrow(); | ||||||
|         .databaseName("Demo") |  | ||||||
|         .connection(connection) |  | ||||||
|         .build(); |  | ||||||
| DatabaseDoc doc = JdbcDatabaseDocFactory.of().create(config).orElseThrow(); |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Render as Markdown | ## Render as Markdown | ||||||
|  |  | ||||||
| ```java | ```java | ||||||
|  | try(FileOutputStream out=new FileOutputStream("user.md")){ | ||||||
|         java.sql.Connection connection=...; |         java.sql.Connection connection=...; | ||||||
| DatabaseDocConfig config = DatabaseDocConfig.builder() |         Databasir databasir=Databasir.of(); | ||||||
|         .databaseName("Demo") |         DatabaseMeta meta=databasir.get(connection,"user").orElseThrow(); | ||||||
|         .connection(connection) |         databasir.renderAsMarkdown(doc,out); | ||||||
|         .build(); |  | ||||||
| DatabaseDoc doc = JdbcDatabaseDocFactory.of().create(config).orElseThrow(); |  | ||||||
| try (FileOutputStream out = new FileOutputStream("doc.md")) { |  | ||||||
|     RenderConfig renderConfig = new RenderConfig(); |  | ||||||
|     Render.markdownRender(renderConfig).rendering(doc, out); |  | ||||||
|         }catch(IOException e){ |         }catch(IOException e){ | ||||||
|         throw new IllegalStateException(e); |         throw new IllegalStateException(e); | ||||||
|         } |         } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| - Example | - Markdown Example | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -44,36 +37,31 @@ support regex pattern to ignore table or column | |||||||
|  |  | ||||||
| ```java | ```java | ||||||
| java.sql.Connection connection=...; | java.sql.Connection connection=...; | ||||||
| DatabaseDocConfig config = DatabaseDocConfig.builder() |         DatabasirConfig config=new DatabasirConfig(); | ||||||
|         .databaseName("Demo") |         config.ignoreColumn("id*"); | ||||||
|         .connection(connection) |         config.ignoreTable("flyway.*"); | ||||||
|         .ignoreTableRegexes(Arrays.asList("mysql_*")) |         DatabaseMeta meta=Databasir.of(config).get(connection,"user").orElseThrow(); | ||||||
|         .ignoreColumnRegexes(Arrays.asList("id")) |  | ||||||
|         .build(); |  | ||||||
| DatabaseDoc doc = JdbcDatabaseDocFactory.of().create(config).orElseThrow(); |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Extension | ## Extension | ||||||
|  |  | ||||||
| Default factory |  | ||||||
|  |  | ||||||
| - tableDocFactory ->  `com.databasir.core.doc.factory.jdbc.JdbcTableDocFactory` |  | ||||||
| - columnDocFactory -> `com.databasir.core.doc.factory.jdbc.JdbcTableColumnDocFactory` |  | ||||||
| - indexDocFactory -> `com.databasir.core.doc.factory.jdbc.JdbcTableIndexDocFactory` |  | ||||||
| - triggerDocFactory -> `com.databasir.core.doc.factory.jdbc.JdbcTableTriggerDocFactory` |  | ||||||
|  |  | ||||||
| Custom configuration | Custom configuration | ||||||
|  |  | ||||||
| ```java | ```java | ||||||
| java.sql.Connection connection=...; | java.sql.Connection connection=...; | ||||||
| DatabaseDocConfig config = DatabaseDocConfig.builder() |         DatabasirConfig config=new DatabasirConfig(); | ||||||
|         .databaseName("Demo") |         config.setDatabaseMetaRepository(...); // your custom repository | ||||||
|         .connection(connection) |         config.setTableMetaRepository(...); // your custom repository | ||||||
|         .tableDocFactory(...) // your custom table doc factory |         config.setColumnMetaRepository(...); // your custom repository | ||||||
|         .tableColumnDocFactory(...) // your custom column doc factory |         config.setTriggerMetaRepository(...); // your custom repository | ||||||
|         .tableIndexDocFactory(...) // your custom index doc factory |         config.setIndexMetaRepository(...); // your custom repository | ||||||
|         .tableTriggerDocFactory(...) // your custom trigger doc factory |         DatabaseMeta meta=Databasir.of().get(connection,"user").orElseThrow(); | ||||||
|         .build(); |  | ||||||
| DatabaseDoc doc = JdbcDatabaseDocFactory.of().create(config).orElseThrow(); |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | Default Repository Is | ||||||
|  |  | ||||||
|  | - com.databasir.core.meta.repository.impl.jdbc.JdbcDatabaseMetaRepository | ||||||
|  | - com.databasir.core.meta.repository.impl.jdbc.JdbcTableMetaRepository | ||||||
|  | - com.databasir.core.meta.repository.impl.jdbc.JdbcColumnMetaRepository | ||||||
|  | - com.databasir.core.meta.repository.impl.jdbc.JdbcIndexMetaRepository | ||||||
|  | - com.databasir.core.meta.repository.impl.jdbc.JdbcTriggerMetaRepository | ||||||
| @@ -6,7 +6,7 @@ subprojects { | |||||||
|  |  | ||||||
|     apply plugin: 'java' |     apply plugin: 'java' | ||||||
|  |  | ||||||
|     group 'cc.cc1234' |     group 'com.databasir' | ||||||
|     version '1.0-SNAPSHOT' |     version '1.0-SNAPSHOT' | ||||||
|  |  | ||||||
|     repositories { |     repositories { | ||||||
|   | |||||||
							
								
								
									
										46
									
								
								core/src/main/java/com/databasir/core/Databasir.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								core/src/main/java/com/databasir/core/Databasir.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | package com.databasir.core; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.DatabaseMeta; | ||||||
|  | import com.databasir.core.meta.repository.condition.Condition; | ||||||
|  | import com.databasir.core.render.Render; | ||||||
|  | import com.databasir.core.render.RenderConfig; | ||||||
|  | import lombok.Getter; | ||||||
|  | import lombok.RequiredArgsConstructor; | ||||||
|  |  | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.OutputStream; | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @RequiredArgsConstructor | ||||||
|  | @Getter | ||||||
|  | public class Databasir { | ||||||
|  |  | ||||||
|  |     private final DatabasirConfig config; | ||||||
|  |  | ||||||
|  |     public Optional<DatabaseMeta> get(Connection connection, String databaseName) { | ||||||
|  |         Condition condition = Condition.builder() | ||||||
|  |                 .databaseName(databaseName) | ||||||
|  |                 .ignoreTableNameRegex(config.getIgnoreTableNameRegex()) | ||||||
|  |                 .ignoreTableColumnNameRegex(config.getIgnoreTableColumnNameRegex()) | ||||||
|  |                 .build(); | ||||||
|  |         return config.getDatabaseMetaRepository().select(connection, condition); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void renderAsMarkdown(DatabaseMeta meta, OutputStream out) throws IOException { | ||||||
|  |         renderAsMarkdown(new RenderConfig(), meta, out); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void renderAsMarkdown(RenderConfig config, DatabaseMeta meta, OutputStream stream) throws IOException { | ||||||
|  |         Render.markdownRender(config).rendering(meta, stream); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static Databasir of() { | ||||||
|  |         return of(new DatabasirConfig()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static Databasir of(DatabasirConfig config) { | ||||||
|  |         return new Databasir(config); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								core/src/main/java/com/databasir/core/DatabasirConfig.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								core/src/main/java/com/databasir/core/DatabasirConfig.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | package com.databasir.core; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.repository.*; | ||||||
|  | import com.databasir.core.meta.repository.impl.jdbc.*; | ||||||
|  | import lombok.Getter; | ||||||
|  | import lombok.Setter; | ||||||
|  |  | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.HashSet; | ||||||
|  |  | ||||||
|  | @Getter | ||||||
|  | @Setter | ||||||
|  | public class DatabasirConfig { | ||||||
|  |  | ||||||
|  |     private IndexMetaRepository indexMetaRepository = new JdbcIndexMetaRepository(); | ||||||
|  |  | ||||||
|  |     private TriggerMetaRepository triggerMetaRepository = new JdbcTriggerMetaRepository(); | ||||||
|  |  | ||||||
|  |     private ColumnMetaRepository columnMetaRepository = new JdbcColumnMetaRepository(); | ||||||
|  |  | ||||||
|  |     private TableMetaRepository tableMetaRepository = | ||||||
|  |             new JdbcTableMetaRepository(columnMetaRepository, indexMetaRepository, triggerMetaRepository); | ||||||
|  |  | ||||||
|  |     private DatabaseMetaRepository databaseMetaRepository = new JdbcDatabaseMetaRepository(tableMetaRepository); | ||||||
|  |  | ||||||
|  |     private Collection<String> ignoreTableNameRegex = new HashSet<>(); | ||||||
|  |  | ||||||
|  |     private Collection<String> ignoreTableColumnNameRegex = new HashSet<>(); | ||||||
|  |  | ||||||
|  |     public DatabasirConfig ignoreTable(String tableNameRegex) { | ||||||
|  |         ignoreTableNameRegex.add(tableNameRegex); | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public DatabasirConfig ignoreColumn(String columnNameRegex) { | ||||||
|  |         ignoreTableColumnNameRegex.add(columnNameRegex); | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,49 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.factory.jdbc.*; |  | ||||||
| import lombok.Builder; |  | ||||||
| import lombok.Getter; |  | ||||||
| import lombok.NonNull; |  | ||||||
|  |  | ||||||
| import java.sql.Connection; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.regex.Pattern; |  | ||||||
|  |  | ||||||
| @Builder |  | ||||||
| @Getter |  | ||||||
| public class DatabaseDocConfig { |  | ||||||
|  |  | ||||||
|     @NonNull |  | ||||||
|     private String databaseName; |  | ||||||
|  |  | ||||||
|     @NonNull |  | ||||||
|     private Connection connection; |  | ||||||
|  |  | ||||||
|     @Builder.Default |  | ||||||
|     private List<String> ignoreTableRegexes = Collections.emptyList(); |  | ||||||
|  |  | ||||||
|     @Builder.Default |  | ||||||
|     private List<String> ignoreColumnRegexes = Collections.emptyList(); |  | ||||||
|  |  | ||||||
|     @Builder.Default |  | ||||||
|     private TableDocFactory tableDocFactory = new JdbcTableDocFactory(); |  | ||||||
|  |  | ||||||
|     @Builder.Default |  | ||||||
|     private TableIndexDocFactory tableIndexDocFactory = new JdbcTableIndexDocFactory(); |  | ||||||
|  |  | ||||||
|     @Builder.Default |  | ||||||
|     private TableTriggerDocFactory tableTriggerDocFactory = new JdbcTableTriggerDocFactory(); |  | ||||||
|  |  | ||||||
|     @Builder.Default |  | ||||||
|     private TableColumnDocFactory tableColumnDocFactory = new JdbcTableColumnDocFactory(); |  | ||||||
|  |  | ||||||
|     public boolean tableIsIgnored(String tableName) { |  | ||||||
|         return ignoreTableRegexes.stream().anyMatch(regex -> Pattern.matches(regex, tableName)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public boolean columnIsIgnored(String column) { |  | ||||||
|         return ignoreColumnRegexes.stream().anyMatch(regex -> Pattern.matches(regex, column)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.model.DatabaseDoc; |  | ||||||
|  |  | ||||||
| import java.util.Optional; |  | ||||||
|  |  | ||||||
| public interface DatabaseDocFactory extends Sortable<DatabaseDocFactory> { |  | ||||||
|  |  | ||||||
|     Optional<DatabaseDoc> create(DatabaseDocConfig configuration); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory; |  | ||||||
|  |  | ||||||
| public interface Sortable<T extends Sortable<?>> extends Comparable<T> { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @return priority, min -> max means low -> high |  | ||||||
|      */ |  | ||||||
|     default int order() { |  | ||||||
|         return Integer.MIN_VALUE; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     default int compareTo(T o) { |  | ||||||
|         return Integer.compare(this.order(), o.order()); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.model.ColumnDoc; |  | ||||||
|  |  | ||||||
| import java.sql.DatabaseMetaData; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| public interface TableColumnDocFactory extends Sortable<TableColumnDocFactory> { |  | ||||||
|  |  | ||||||
|     List<ColumnDoc> create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.model.TableDoc; |  | ||||||
|  |  | ||||||
| import java.sql.DatabaseMetaData; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| public interface TableDocFactory extends Sortable<TableDocFactory> { |  | ||||||
|  |  | ||||||
|     List<TableDoc> create(DatabaseMetaData metaData, DatabaseDocConfig configuration); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.model.IndexDoc; |  | ||||||
|  |  | ||||||
| import java.sql.DatabaseMetaData; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| public interface TableIndexDocFactory extends Sortable<TableIndexDocFactory> { |  | ||||||
|  |  | ||||||
|     List<IndexDoc> create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.model.TriggerDoc; |  | ||||||
|  |  | ||||||
| import java.sql.DatabaseMetaData; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| public interface TableTriggerDocFactory extends Sortable<TableTriggerDocFactory> { |  | ||||||
|  |  | ||||||
|     List<TriggerDoc> create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration); |  | ||||||
| } |  | ||||||
| @@ -1,45 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory.jdbc; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.factory.DatabaseDocConfig; |  | ||||||
| import com.databasir.core.doc.factory.*; |  | ||||||
| import com.databasir.core.doc.model.DatabaseDoc; |  | ||||||
| import com.databasir.core.doc.model.TableDoc; |  | ||||||
|  |  | ||||||
| import java.sql.DatabaseMetaData; |  | ||||||
| import java.sql.ResultSet; |  | ||||||
| import java.sql.SQLException; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Objects; |  | ||||||
| import java.util.Optional; |  | ||||||
|  |  | ||||||
| public class JdbcDatabaseDocFactory implements DatabaseDocFactory { |  | ||||||
|  |  | ||||||
|     public static JdbcDatabaseDocFactory of() { |  | ||||||
|         return new JdbcDatabaseDocFactory(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Optional<DatabaseDoc> create(DatabaseDocConfig configuration) { |  | ||||||
|         try { |  | ||||||
|             DatabaseMetaData metaData = configuration.getConnection().getMetaData(); |  | ||||||
|             ResultSet catalogs = metaData.getCatalogs(); |  | ||||||
|             while (catalogs.next()) { |  | ||||||
|                 String catalogName = catalogs.getString("TABLE_CAT"); |  | ||||||
|                 if (Objects.equals(configuration.getDatabaseName(), catalogName)) { |  | ||||||
|                     TableDocFactory tableDocFactory = configuration.getTableDocFactory(); |  | ||||||
|                     List<TableDoc> tableDocs = tableDocFactory.create(metaData, configuration); |  | ||||||
|                     DatabaseDoc databaseDoc = DatabaseDoc.builder() |  | ||||||
|                             .productName(metaData.getDatabaseProductName()) |  | ||||||
|                             .productVersion(metaData.getDatabaseProductVersion()) |  | ||||||
|                             .databaseName(catalogName) |  | ||||||
|                             .tables(tableDocs) |  | ||||||
|                             .build(); |  | ||||||
|                     return Optional.of(databaseDoc); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return Optional.empty(); |  | ||||||
|         } catch (SQLException e) { |  | ||||||
|             throw new IllegalStateException(e); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,59 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory.jdbc; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.factory.DatabaseDocConfig; |  | ||||||
| import com.databasir.core.doc.factory.*; |  | ||||||
| import com.databasir.core.doc.model.TableDoc; |  | ||||||
| import lombok.extern.slf4j.Slf4j; |  | ||||||
|  |  | ||||||
| import java.sql.DatabaseMetaData; |  | ||||||
| import java.sql.ResultSet; |  | ||||||
| import java.sql.SQLException; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| @Slf4j |  | ||||||
| public class JdbcTableDocFactory implements TableDocFactory { |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public List<TableDoc> create(DatabaseMetaData metaData, |  | ||||||
|                                  DatabaseDocConfig configuration) { |  | ||||||
|         try { |  | ||||||
|             return doCreateTableDoc(metaData, configuration); |  | ||||||
|         } catch (SQLException e) { |  | ||||||
|             throw new IllegalStateException(e); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private List<TableDoc> doCreateTableDoc(DatabaseMetaData metaData, |  | ||||||
|                                             DatabaseDocConfig configuration) throws SQLException { |  | ||||||
|         List<TableDoc> tableDocs = new ArrayList<>(); |  | ||||||
|         if (metaData == null) { |  | ||||||
|             return tableDocs; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         String databaseName = configuration.getDatabaseName(); |  | ||||||
|         ResultSet tablesResult = metaData.getTables(databaseName, null, null, null); |  | ||||||
|         while (tablesResult.next()) { |  | ||||||
|             String tableName = tablesResult.getString("TABLE_NAME"); |  | ||||||
|             if (configuration.tableIsIgnored(tableName)) { |  | ||||||
|                 if (log.isWarnEnabled()) { |  | ||||||
|                     log.warn("ignore table: " + configuration.getDatabaseName() + "." + tableName); |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 String tableType = tablesResult.getString("TABLE_TYPE"); |  | ||||||
|                 String tableComment = tablesResult.getString("REMARKS"); |  | ||||||
|                 TableDoc tableDoc = TableDoc.builder() |  | ||||||
|                         .tableName(tableName) |  | ||||||
|                         .tableType(tableType) |  | ||||||
|                         .tableComment(tableComment) |  | ||||||
|                         .columns(configuration.getTableColumnDocFactory().create(tableName, metaData, configuration)) |  | ||||||
|                         .indexes(configuration.getTableIndexDocFactory().create(tableName, metaData, configuration)) |  | ||||||
|                         .triggers(configuration.getTableTriggerDocFactory().create(tableName, metaData, configuration)) |  | ||||||
|                         .build(); |  | ||||||
|                 tableDocs.add(tableDoc); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return tableDocs; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,64 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory.jdbc; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.factory.DatabaseDocConfig; |  | ||||||
| import com.databasir.core.doc.factory.TableIndexDocFactory; |  | ||||||
| import com.databasir.core.doc.model.IndexDoc; |  | ||||||
| import lombok.extern.slf4j.Slf4j; |  | ||||||
|  |  | ||||||
| import java.sql.DatabaseMetaData; |  | ||||||
| import java.sql.ResultSet; |  | ||||||
| import java.sql.SQLException; |  | ||||||
| import java.util.*; |  | ||||||
|  |  | ||||||
| @Slf4j |  | ||||||
| public class JdbcTableIndexDocFactory implements TableIndexDocFactory { |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public List<IndexDoc> create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration) { |  | ||||||
|         try { |  | ||||||
|             return doCreateIndexDocs(tableName, metaData, configuration); |  | ||||||
|         } catch (SQLException e) { |  | ||||||
|             throw new IllegalStateException(e); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private List<IndexDoc> doCreateIndexDocs(String tableName, |  | ||||||
|                                              DatabaseMetaData metaData, |  | ||||||
|                                              DatabaseDocConfig configuration) |  | ||||||
|             throws SQLException { |  | ||||||
|         List<IndexDoc> indexDocs = new ArrayList<>(); |  | ||||||
|         String databaseName = configuration.getDatabaseName(); |  | ||||||
|         if (tableName == null || metaData == null) { |  | ||||||
|             return indexDocs; |  | ||||||
|         } |  | ||||||
|         ResultSet indexResults; |  | ||||||
|         try { |  | ||||||
|             indexResults = metaData.getIndexInfo(databaseName, null, tableName, false, false); |  | ||||||
|         } catch (SQLException e) { |  | ||||||
|             log.warn("warn: ignore " + databaseName + "." + tableName); |  | ||||||
|             return indexDocs; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Map<String, IndexDoc> docsGroupByName = new HashMap<>(); |  | ||||||
|         while (indexResults.next()) { |  | ||||||
|             Boolean nonUnique = indexResults.getBoolean("NON_UNIQUE"); |  | ||||||
|             String indexName = indexResults.getString("INDEX_NAME"); |  | ||||||
|             String columnName = indexResults.getString("COLUMN_NAME"); |  | ||||||
|             if (docsGroupByName.containsKey(indexName)) { |  | ||||||
|                 docsGroupByName.get(indexName).getColumnNames().add(columnName); |  | ||||||
|             } else { |  | ||||||
|                 List<String> columns = new ArrayList<>(); |  | ||||||
|                 columns.add(columnName); |  | ||||||
|                 IndexDoc columnDoc = IndexDoc.builder() |  | ||||||
|                         .indexName(indexName) |  | ||||||
|                         .columnNames(columns) |  | ||||||
|                         .isPrimaryKey(Objects.equals("PRIMARY", indexName)) |  | ||||||
|                         .isUniqueKey(Objects.equals(nonUnique, false)) |  | ||||||
|                         .build(); |  | ||||||
|                 docsGroupByName.put(indexName, columnDoc); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return new ArrayList<>(docsGroupByName.values()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| package com.databasir.core.doc.factory.jdbc; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.factory.DatabaseDocConfig; |  | ||||||
| import com.databasir.core.doc.factory.TableTriggerDocFactory; |  | ||||||
| import com.databasir.core.doc.model.TriggerDoc; |  | ||||||
|  |  | ||||||
| import java.sql.DatabaseMetaData; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| public class JdbcTableTriggerDocFactory implements TableTriggerDocFactory { |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public List<TriggerDoc> create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration) { |  | ||||||
|         // note: jdbc not support get triggers |  | ||||||
|         return Collections.emptyList(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| package com.databasir.core.doc.render; |  | ||||||
|  |  | ||||||
| import com.databasir.core.doc.model.DatabaseDoc; |  | ||||||
| import com.databasir.core.doc.render.markdown.MarkdownRender; |  | ||||||
|  |  | ||||||
| import java.io.IOException; |  | ||||||
| import java.io.OutputStream; |  | ||||||
|  |  | ||||||
| public interface Render { |  | ||||||
|  |  | ||||||
|     void rendering(DatabaseDoc doc, OutputStream outputStream) throws IOException; |  | ||||||
|  |  | ||||||
|     static Render markdownRender(RenderConfig configuration) { |  | ||||||
|         return MarkdownRender.of(configuration); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,11 +1,11 @@ | |||||||
| package com.databasir.core.doc.model; | package com.databasir.core.meta.pojo; | ||||||
| 
 | 
 | ||||||
| import lombok.Builder; | import lombok.Builder; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| 
 | 
 | ||||||
| @Data | @Data | ||||||
| @Builder | @Builder | ||||||
| public class ColumnDoc { | public class ColumnMeta { | ||||||
| 
 | 
 | ||||||
|     private String name; |     private String name; | ||||||
| 
 | 
 | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| package com.databasir.core.doc.model; | package com.databasir.core.meta.pojo; | ||||||
| 
 | 
 | ||||||
| import lombok.Builder; | import lombok.Builder; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| @@ -8,21 +8,36 @@ import java.util.List; | |||||||
| 
 | 
 | ||||||
| @Data | @Data | ||||||
| @Builder | @Builder | ||||||
| public class DatabaseDoc { | public class DatabaseMeta { | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * product_name | ||||||
|  |      */ | ||||||
|     private String productName; |     private String productName; | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * product_version | ||||||
|  |      */ | ||||||
|     private String productVersion; |     private String productVersion; | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * driver_name | ||||||
|  |      */ | ||||||
|     private String driverName; |     private String driverName; | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * driver_version | ||||||
|  |      */ | ||||||
|     private String driverVersion; |     private String driverVersion; | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * database_name | ||||||
|  |      */ | ||||||
|     private String databaseName; |     private String databaseName; | ||||||
| 
 | 
 | ||||||
|     private String remark; |     private String remark; | ||||||
| 
 | 
 | ||||||
|     @Builder.Default |     @Builder.Default | ||||||
|     private List<TableDoc> tables = Collections.emptyList(); |     private List<TableMeta> tables = Collections.emptyList(); | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| package com.databasir.core.doc.model; | package com.databasir.core.meta.pojo; | ||||||
| 
 | 
 | ||||||
| import lombok.Builder; | import lombok.Builder; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| @@ -8,7 +8,7 @@ import java.util.List; | |||||||
| 
 | 
 | ||||||
| @Data | @Data | ||||||
| @Builder | @Builder | ||||||
| public class IndexDoc { | public class IndexMeta { | ||||||
| 
 | 
 | ||||||
|     private String indexName; |     private String indexName; | ||||||
| 
 | 
 | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| package com.databasir.core.doc.model; | package com.databasir.core.meta.pojo; | ||||||
| 
 | 
 | ||||||
| import lombok.Builder; | import lombok.Builder; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| @@ -8,7 +8,7 @@ import java.util.List; | |||||||
| 
 | 
 | ||||||
| @Data | @Data | ||||||
| @Builder | @Builder | ||||||
| public class TableDoc { | public class TableMeta { | ||||||
| 
 | 
 | ||||||
|     private String tableName; |     private String tableName; | ||||||
| 
 | 
 | ||||||
| @@ -17,13 +17,13 @@ public class TableDoc { | |||||||
|     private String tableComment; |     private String tableComment; | ||||||
| 
 | 
 | ||||||
|     @Builder.Default |     @Builder.Default | ||||||
|     private List<ColumnDoc> columns = Collections.emptyList(); |     private List<ColumnMeta> columns = Collections.emptyList(); | ||||||
| 
 | 
 | ||||||
|     @Builder.Default |     @Builder.Default | ||||||
|     private List<TriggerDoc> triggers = Collections.emptyList(); |     private List<TriggerMeta> triggers = Collections.emptyList(); | ||||||
| 
 | 
 | ||||||
|     @Builder.Default |     @Builder.Default | ||||||
|     private List<IndexDoc> indexes = Collections.emptyList(); |     private List<IndexMeta> indexes = Collections.emptyList(); | ||||||
| 
 | 
 | ||||||
|     private String remark; |     private String remark; | ||||||
| } | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| package com.databasir.core.doc.model; | package com.databasir.core.meta.pojo; | ||||||
| 
 | 
 | ||||||
| import lombok.Builder; | import lombok.Builder; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| @@ -8,7 +8,7 @@ import lombok.Data; | |||||||
|  */ |  */ | ||||||
| @Data | @Data | ||||||
| @Builder | @Builder | ||||||
| public class TriggerDoc { | public class TriggerMeta { | ||||||
| 
 | 
 | ||||||
|     private String name; |     private String name; | ||||||
| 
 | 
 | ||||||
| @@ -0,0 +1,80 @@ | |||||||
|  | package com.databasir.core.meta.provider; | ||||||
|  |  | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * TODO use to extension repository | ||||||
|  |  */ | ||||||
|  | public interface SqlProvider { | ||||||
|  |  | ||||||
|  |     Default DEFAULT = new Default(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * <p> | ||||||
|  |      * generate sql to select database information, should return the follow columns | ||||||
|  |      * </p> | ||||||
|  |      * | ||||||
|  |      * <table> | ||||||
|  |      *     <tr> | ||||||
|  |      *         <th> column name </th> | ||||||
|  |      *         <th> column type </th> | ||||||
|  |      *         <th> description </th> | ||||||
|  |      *         <th> nullable </th> | ||||||
|  |      *     </tr> | ||||||
|  |      *     <tr> | ||||||
|  |      *         <td> TABLE_CAT </td> | ||||||
|  |      *         <td> String </td> | ||||||
|  |      *         <td> catalog name </td> | ||||||
|  |      *         <td> NO </td> | ||||||
|  |      *     </tr> | ||||||
|  |      * </table> | ||||||
|  |      * <br> | ||||||
|  |      * | ||||||
|  |      * @param databaseName | ||||||
|  |      * @return | ||||||
|  |      */ | ||||||
|  |     default Optional<String> databaseMetaSql(String databaseName) { | ||||||
|  |         return Optional.empty(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * generate sql to select table information, should return the follow columns | ||||||
|  |      * <table> | ||||||
|  |      *     <tr> | ||||||
|  |      *         <th> column name </th> | ||||||
|  |      *         <th> column type </th> | ||||||
|  |      *         <th> description </th> | ||||||
|  |      *         <th> nullable </th> | ||||||
|  |      *     </tr> | ||||||
|  |      *     <tr> | ||||||
|  |      *         <td> TABLE_CAT </td> | ||||||
|  |      *         <td> String </td> | ||||||
|  |      *         <td> catalog name </td> | ||||||
|  |      *         <td> NO </td> | ||||||
|  |      *     </tr> | ||||||
|  |      * </table> | ||||||
|  |      * | ||||||
|  |      * @param databaseName | ||||||
|  |      * @param tableName | ||||||
|  |      * @return | ||||||
|  |      */ | ||||||
|  |     default Optional<String> tableMetaSql(String databaseName, String tableName) { | ||||||
|  |         return Optional.empty(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     default Optional<String> tableColumnMetaSql(String databaseName, String tableName) { | ||||||
|  |         return Optional.empty(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     default Optional<String> tableIndexMetaSql(String databaseName, String tableName) { | ||||||
|  |         return Optional.empty(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     default Optional<String> tableTriggerMetaSql(String databaseName, String tableName) { | ||||||
|  |         return Optional.empty(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     class Default implements SqlProvider { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | package com.databasir.core.meta.repository; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.ColumnMeta; | ||||||
|  | import com.databasir.core.meta.repository.condition.TableCondition; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public interface ColumnMetaRepository { | ||||||
|  |  | ||||||
|  |     List<ColumnMeta> selectColumns(Connection connection, TableCondition condition); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | package com.databasir.core.meta.repository; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.DatabaseMeta; | ||||||
|  | import com.databasir.core.meta.repository.condition.Condition; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | public interface DatabaseMetaRepository { | ||||||
|  |  | ||||||
|  |     Optional<DatabaseMeta> select(Connection connection, Condition condition); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | package com.databasir.core.meta.repository; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.IndexMeta; | ||||||
|  | import com.databasir.core.meta.repository.condition.TableCondition; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public interface IndexMetaRepository { | ||||||
|  |  | ||||||
|  |     List<IndexMeta> selectIndexes(Connection connection, TableCondition condition); | ||||||
|  | } | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | package com.databasir.core.meta.repository; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.TableMeta; | ||||||
|  | import com.databasir.core.meta.repository.condition.Condition; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public interface TableMetaRepository { | ||||||
|  |  | ||||||
|  |     List<TableMeta> selectTables(Connection connection, Condition condition); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | package com.databasir.core.meta.repository; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.TriggerMeta; | ||||||
|  | import com.databasir.core.meta.repository.condition.TableCondition; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public interface TriggerMetaRepository { | ||||||
|  |  | ||||||
|  |     List<TriggerMeta> selectTriggers(Connection connection, TableCondition condition); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | package com.databasir.core.meta.repository.condition; | ||||||
|  |  | ||||||
|  | import lombok.Builder; | ||||||
|  | import lombok.Getter; | ||||||
|  | import lombok.NonNull; | ||||||
|  | import lombok.experimental.SuperBuilder; | ||||||
|  |  | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.regex.Pattern; | ||||||
|  |  | ||||||
|  | @SuperBuilder | ||||||
|  | @Getter | ||||||
|  | public class Condition { | ||||||
|  |  | ||||||
|  |     @NonNull | ||||||
|  |     private String databaseName; | ||||||
|  |  | ||||||
|  |     @Builder.Default | ||||||
|  |     private Collection<String> ignoreTableNameRegex = Collections.emptyList(); | ||||||
|  |  | ||||||
|  |     @Builder.Default | ||||||
|  |     private Collection<String> ignoreTableColumnNameRegex = Collections.emptyList(); | ||||||
|  |  | ||||||
|  |     public boolean tableIsIgnored(String tableName) { | ||||||
|  |         return ignoreTableNameRegex.stream().anyMatch(regex -> Pattern.matches(regex, tableName)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean columnIsIgnored(String column) { | ||||||
|  |         return ignoreTableColumnNameRegex.stream().anyMatch(regex -> Pattern.matches(regex, column)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | package com.databasir.core.meta.repository.condition; | ||||||
|  |  | ||||||
|  | import lombok.Getter; | ||||||
|  | import lombok.NonNull; | ||||||
|  | import lombok.experimental.SuperBuilder; | ||||||
|  |  | ||||||
|  | @SuperBuilder | ||||||
|  | @Getter | ||||||
|  | public class TableCondition extends Condition { | ||||||
|  |  | ||||||
|  |     @NonNull | ||||||
|  |     private String tableName; | ||||||
|  |  | ||||||
|  |     public static TableCondition of(Condition condition, String tableName) { | ||||||
|  |         return TableCondition.builder() | ||||||
|  |                 .databaseName(condition.getDatabaseName()) | ||||||
|  |                 .tableName(tableName) | ||||||
|  |                 .ignoreTableNameRegex(condition.getIgnoreTableNameRegex()) | ||||||
|  |                 .ignoreTableColumnNameRegex(condition.getIgnoreTableColumnNameRegex()) | ||||||
|  |                 .build(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,11 +1,11 @@ | |||||||
| package com.databasir.core.doc.factory.extension.mysql; | package com.databasir.core.meta.repository.impl.extension; | ||||||
| 
 | 
 | ||||||
| import com.databasir.core.doc.factory.DatabaseDocConfig; | import com.databasir.core.meta.pojo.TriggerMeta; | ||||||
| import com.databasir.core.doc.factory.TableTriggerDocFactory; | import com.databasir.core.meta.repository.TriggerMetaRepository; | ||||||
| import com.databasir.core.doc.model.TriggerDoc; | import com.databasir.core.meta.repository.condition.TableCondition; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| 
 | 
 | ||||||
| import java.sql.DatabaseMetaData; | import java.sql.Connection; | ||||||
| import java.sql.PreparedStatement; | import java.sql.PreparedStatement; | ||||||
| import java.sql.ResultSet; | import java.sql.ResultSet; | ||||||
| import java.sql.SQLException; | import java.sql.SQLException; | ||||||
| @@ -14,12 +14,10 @@ import java.util.Collections; | |||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| @Slf4j | @Slf4j | ||||||
| public class MysqlTableTriggerDocFactory implements TableTriggerDocFactory { | public class MysqlTableTriggerMetaRepository implements TriggerMetaRepository { | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public List<TriggerDoc> create(String tableName, |     public List<TriggerMeta> selectTriggers(Connection connection, TableCondition condition) { | ||||||
|                                    DatabaseMetaData metaData, |  | ||||||
|                                    DatabaseDocConfig configuration) { |  | ||||||
|         String sql = "SELECT TRIGGER_CATALOG,\n" + |         String sql = "SELECT TRIGGER_CATALOG,\n" + | ||||||
|                 "       TRIGGER_SCHEMA,\n" + |                 "       TRIGGER_SCHEMA,\n" + | ||||||
|                 "       TRIGGER_NAME,\n" + |                 "       TRIGGER_NAME,\n" + | ||||||
| @@ -41,26 +39,25 @@ public class MysqlTableTriggerDocFactory implements TableTriggerDocFactory { | |||||||
|                 "       DEFINER\n " + |                 "       DEFINER\n " + | ||||||
|                 "FROM information_schema.TRIGGERS WHERE EVENT_OBJECT_SCHEMA = ? AND EVENT_OBJECT_TABLE = ?"; |                 "FROM information_schema.TRIGGERS WHERE EVENT_OBJECT_SCHEMA = ? AND EVENT_OBJECT_TABLE = ?"; | ||||||
|         try { |         try { | ||||||
|             PreparedStatement preparedStatement = configuration.getConnection() |             PreparedStatement preparedStatement = connection.prepareStatement(sql); | ||||||
|                     .prepareStatement(sql); |             preparedStatement.setObject(1, condition.getDatabaseName()); | ||||||
|             preparedStatement.setObject(1, configuration.getDatabaseName()); |             preparedStatement.setObject(2, condition.getTableName()); | ||||||
|             preparedStatement.setObject(2, tableName); |  | ||||||
|             ResultSet results = preparedStatement.executeQuery(); |             ResultSet results = preparedStatement.executeQuery(); | ||||||
|             List<TriggerDoc> triggers = new ArrayList<>(); |             List<TriggerMeta> triggers = new ArrayList<>(); | ||||||
|             while (results.next()) { |             while (results.next()) { | ||||||
|                 String name = results.getString("TRIGGER_NAME"); |                 String name = results.getString("TRIGGER_NAME"); | ||||||
|                 String statement = results.getString("ACTION_STATEMENT"); |                 String statement = results.getString("ACTION_STATEMENT"); | ||||||
|                 String timing = results.getString("ACTION_TIMING"); |                 String timing = results.getString("ACTION_TIMING"); | ||||||
|                 String manipulation = results.getString("EVENT_MANIPULATION"); |                 String manipulation = results.getString("EVENT_MANIPULATION"); | ||||||
|                 String created = results.getString("CREATED"); |                 String created = results.getString("CREATED"); | ||||||
|                 TriggerDoc doc = TriggerDoc.builder() |                 TriggerMeta meta = TriggerMeta.builder() | ||||||
|                         .name(name) |                         .name(name) | ||||||
|                         .manipulation(manipulation) |                         .manipulation(manipulation) | ||||||
|                         .timing(timing) |                         .timing(timing) | ||||||
|                         .statement(statement) |                         .statement(statement) | ||||||
|                         .createAt(created) |                         .createAt(created) | ||||||
|                         .build(); |                         .build(); | ||||||
|                 triggers.add(doc); |                 triggers.add(meta); | ||||||
|             } |             } | ||||||
|             return triggers; |             return triggers; | ||||||
|         } catch (SQLException e) { |         } catch (SQLException e) { | ||||||
| @@ -1,11 +1,12 @@ | |||||||
| package com.databasir.core.doc.factory.jdbc; | package com.databasir.core.meta.repository.impl.jdbc; | ||||||
| 
 | 
 | ||||||
| import com.databasir.core.doc.factory.DatabaseDocConfig; | import com.databasir.core.meta.pojo.ColumnMeta; | ||||||
| import com.databasir.core.doc.factory.TableColumnDocFactory; | import com.databasir.core.meta.repository.ColumnMetaRepository; | ||||||
| import com.databasir.core.doc.model.ColumnDoc; | import com.databasir.core.meta.repository.condition.TableCondition; | ||||||
|  | import lombok.RequiredArgsConstructor; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| 
 | 
 | ||||||
| import java.sql.DatabaseMetaData; | import java.sql.Connection; | ||||||
| import java.sql.ResultSet; | import java.sql.ResultSet; | ||||||
| import java.sql.SQLException; | import java.sql.SQLException; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| @@ -13,34 +14,32 @@ import java.util.List; | |||||||
| import java.util.Objects; | import java.util.Objects; | ||||||
| 
 | 
 | ||||||
| @Slf4j | @Slf4j | ||||||
| public class JdbcTableColumnDocFactory implements TableColumnDocFactory { | @RequiredArgsConstructor | ||||||
|  | public class JdbcColumnMetaRepository implements ColumnMetaRepository { | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public List<ColumnDoc> create(String tableName, |     public List<ColumnMeta> selectColumns(Connection connection, TableCondition tableCondition) { | ||||||
|                                   DatabaseMetaData metaData, |  | ||||||
|                                   DatabaseDocConfig configuration) { |  | ||||||
|         try { |         try { | ||||||
|             return doCreate(tableName, metaData, configuration); |             return doSelect(connection, tableCondition); | ||||||
|         } catch (SQLException e) { |         } catch (SQLException e) { | ||||||
|             throw new IllegalStateException(e); |             throw new IllegalStateException(e); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private List<ColumnDoc> doCreate(String tableName, |     private List<ColumnMeta> doSelect(Connection connection, TableCondition tableCondition) throws SQLException { | ||||||
|                                      DatabaseMetaData metaData, |         List<ColumnMeta> columnDocs = new ArrayList<>(); | ||||||
|                                      DatabaseDocConfig configuration) throws SQLException { |         String databaseName = tableCondition.getDatabaseName(); | ||||||
|         List<ColumnDoc> columnDocs = new ArrayList<>(); |         String tableName = tableCondition.getTableName(); | ||||||
|         String database = configuration.getDatabaseName(); |  | ||||||
|         ResultSet columnsResult; |         ResultSet columnsResult; | ||||||
|         try { |         try { | ||||||
|             columnsResult = metaData.getColumns(database, null, tableName, null); |             columnsResult = connection.getMetaData().getColumns(databaseName, null, tableName, null); | ||||||
|         } catch (SQLException e) { |         } catch (SQLException e) { | ||||||
|             log.warn("warn: ignore columns in " + database + "." + tableName); |             log.warn("warn: ignore columns in " + databaseName + "." + tableName); | ||||||
|             return columnDocs; |             return columnDocs; | ||||||
|         } |         } | ||||||
|         while (columnsResult.next()) { |         while (columnsResult.next()) { | ||||||
|             String columnName = columnsResult.getString("COLUMN_NAME"); |             String columnName = columnsResult.getString("COLUMN_NAME"); | ||||||
|             if (configuration.columnIsIgnored(columnName)) { |             if (tableCondition.columnIsIgnored(columnName)) { | ||||||
|                 if (log.isWarnEnabled()) { |                 if (log.isWarnEnabled()) { | ||||||
|                     log.warn("ignore column: " + columnName); |                     log.warn("ignore column: " + columnName); | ||||||
|                 } |                 } | ||||||
| @@ -52,7 +51,7 @@ public class JdbcTableColumnDocFactory implements TableColumnDocFactory { | |||||||
|                 boolean isNullable = Objects.equals("YES", columnsResult.getString("IS_NULLABLE")); |                 boolean isNullable = Objects.equals("YES", columnsResult.getString("IS_NULLABLE")); | ||||||
|                 boolean isAutoIncrement = Objects.equals("YES", columnsResult.getString("IS_AUTOINCREMENT")); |                 boolean isAutoIncrement = Objects.equals("YES", columnsResult.getString("IS_AUTOINCREMENT")); | ||||||
|                 String columnComment = columnsResult.getString("REMARKS"); |                 String columnComment = columnsResult.getString("REMARKS"); | ||||||
|                 ColumnDoc columnDoc = ColumnDoc.builder() |                 ColumnMeta columnMeta = ColumnMeta.builder() | ||||||
|                         .name(columnName) |                         .name(columnName) | ||||||
|                         .type(columnType) |                         .type(columnType) | ||||||
|                         .size(columnSize) |                         .size(columnSize) | ||||||
| @@ -62,11 +61,10 @@ public class JdbcTableColumnDocFactory implements TableColumnDocFactory { | |||||||
|                         .comment(columnComment) |                         .comment(columnComment) | ||||||
|                         .defaultValue(defaultValue) |                         .defaultValue(defaultValue) | ||||||
|                         .build(); |                         .build(); | ||||||
|                 columnDocs.add(columnDoc); |                 columnDocs.add(columnMeta); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
|         return columnDocs; |         return columnDocs; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| } | } | ||||||
| @@ -0,0 +1,47 @@ | |||||||
|  | package com.databasir.core.meta.repository.impl.jdbc; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.DatabaseMeta; | ||||||
|  | import com.databasir.core.meta.pojo.TableMeta; | ||||||
|  | import com.databasir.core.meta.repository.DatabaseMetaRepository; | ||||||
|  | import com.databasir.core.meta.repository.TableMetaRepository; | ||||||
|  | import com.databasir.core.meta.repository.condition.Condition; | ||||||
|  | import lombok.RequiredArgsConstructor; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.sql.DatabaseMetaData; | ||||||
|  | import java.sql.ResultSet; | ||||||
|  | import java.sql.SQLException; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Objects; | ||||||
|  | import java.util.Optional; | ||||||
|  |  | ||||||
|  | @RequiredArgsConstructor | ||||||
|  | public class JdbcDatabaseMetaRepository implements DatabaseMetaRepository { | ||||||
|  |  | ||||||
|  |     private final TableMetaRepository tableMetaRepository; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<DatabaseMeta> select(Connection connection, Condition condition) { | ||||||
|  |         try { | ||||||
|  |             DatabaseMetaData metaData = connection.getMetaData(); | ||||||
|  |             ResultSet catalogs = metaData.getCatalogs(); | ||||||
|  |             while (catalogs.next()) { | ||||||
|  |                 String catalogName = catalogs.getString("TABLE_CAT"); | ||||||
|  |                 if (Objects.equals(condition.getDatabaseName(), catalogName)) { | ||||||
|  |                     List<TableMeta> tableDocs = tableMetaRepository.selectTables(connection, condition); | ||||||
|  |                     DatabaseMeta meta = DatabaseMeta.builder() | ||||||
|  |                             .productName(metaData.getDatabaseProductName()) | ||||||
|  |                             .productVersion(metaData.getDatabaseProductVersion()) | ||||||
|  |                             .databaseName(catalogName) | ||||||
|  |                             .tables(tableDocs) | ||||||
|  |                             .build(); | ||||||
|  |                     return Optional.of(meta); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return Optional.empty(); | ||||||
|  |         } catch (SQLException e) { | ||||||
|  |             throw new IllegalStateException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,59 @@ | |||||||
|  | package com.databasir.core.meta.repository.impl.jdbc; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.IndexMeta; | ||||||
|  | import com.databasir.core.meta.repository.IndexMetaRepository; | ||||||
|  | import com.databasir.core.meta.repository.condition.TableCondition; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.sql.ResultSet; | ||||||
|  | import java.sql.SQLException; | ||||||
|  | import java.util.*; | ||||||
|  |  | ||||||
|  | @Slf4j | ||||||
|  | public class JdbcIndexMetaRepository implements IndexMetaRepository { | ||||||
|  |     @Override | ||||||
|  |     public List<IndexMeta> selectIndexes(Connection connection, TableCondition condition) { | ||||||
|  |         try { | ||||||
|  |             return doCreateIndexDocs(connection, condition); | ||||||
|  |         } catch (SQLException e) { | ||||||
|  |             throw new IllegalStateException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private List<IndexMeta> doCreateIndexDocs(Connection connection, TableCondition condition) | ||||||
|  |             throws SQLException { | ||||||
|  |         String databaseName = condition.getDatabaseName(); | ||||||
|  |         String tableName = condition.getTableName(); | ||||||
|  |         List<IndexMeta> indexMetas = new ArrayList<>(); | ||||||
|  |         ResultSet indexResults; | ||||||
|  |         try { | ||||||
|  |             indexResults = connection.getMetaData().getIndexInfo(databaseName, null, tableName, false, false); | ||||||
|  |         } catch (SQLException e) { | ||||||
|  |             log.warn("warn: ignore " + databaseName + "." + tableName); | ||||||
|  |             return indexMetas; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Map<String, IndexMeta> pojoGroupByName = new HashMap<>(); | ||||||
|  |         while (indexResults.next()) { | ||||||
|  |             Boolean nonUnique = indexResults.getBoolean("NON_UNIQUE"); | ||||||
|  |             String indexName = indexResults.getString("INDEX_NAME"); | ||||||
|  |             String columnName = indexResults.getString("COLUMN_NAME"); | ||||||
|  |             if (pojoGroupByName.containsKey(indexName)) { | ||||||
|  |                 pojoGroupByName.get(indexName).getColumnNames().add(columnName); | ||||||
|  |             } else { | ||||||
|  |                 List<String> columns = new ArrayList<>(); | ||||||
|  |                 columns.add(columnName); | ||||||
|  |                 IndexMeta indexMeta = IndexMeta.builder() | ||||||
|  |                         .indexName(indexName) | ||||||
|  |                         .columnNames(columns) | ||||||
|  |                         .isPrimaryKey(Objects.equals("PRIMARY", indexName)) | ||||||
|  |                         .isUniqueKey(Objects.equals(nonUnique, false)) | ||||||
|  |                         .build(); | ||||||
|  |                 pojoGroupByName.put(indexName, indexMeta); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return new ArrayList<>(pojoGroupByName.values()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,66 @@ | |||||||
|  | package com.databasir.core.meta.repository.impl.jdbc; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.TableMeta; | ||||||
|  | import com.databasir.core.meta.repository.ColumnMetaRepository; | ||||||
|  | import com.databasir.core.meta.repository.IndexMetaRepository; | ||||||
|  | import com.databasir.core.meta.repository.TableMetaRepository; | ||||||
|  | import com.databasir.core.meta.repository.TriggerMetaRepository; | ||||||
|  | import com.databasir.core.meta.repository.condition.Condition; | ||||||
|  | import com.databasir.core.meta.repository.condition.TableCondition; | ||||||
|  | import lombok.RequiredArgsConstructor; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.sql.ResultSet; | ||||||
|  | import java.sql.SQLException; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @RequiredArgsConstructor | ||||||
|  | @Slf4j | ||||||
|  | public class JdbcTableMetaRepository implements TableMetaRepository { | ||||||
|  |  | ||||||
|  |     private final ColumnMetaRepository columnMetaRepository; | ||||||
|  |  | ||||||
|  |     private final IndexMetaRepository indexMetaRepository; | ||||||
|  |  | ||||||
|  |     private final TriggerMetaRepository triggerMetaRepository; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<TableMeta> selectTables(Connection connection, Condition condition) { | ||||||
|  |         try { | ||||||
|  |             return doSelect(connection, condition); | ||||||
|  |         } catch (SQLException e) { | ||||||
|  |             throw new IllegalStateException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private List<TableMeta> doSelect(Connection connection, Condition condition) throws SQLException { | ||||||
|  |         List<TableMeta> tableMetas = new ArrayList<>(); | ||||||
|  |         String databaseName = condition.getDatabaseName(); | ||||||
|  |         ResultSet tablesResult = connection.getMetaData().getTables(databaseName, null, null, null); | ||||||
|  |         while (tablesResult.next()) { | ||||||
|  |             String tableName = tablesResult.getString("TABLE_NAME"); | ||||||
|  |             if (condition.tableIsIgnored(tableName)) { | ||||||
|  |                 if (log.isWarnEnabled()) { | ||||||
|  |                     log.warn("ignored table: " + databaseName + "." + tableName); | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 String tableType = tablesResult.getString("TABLE_TYPE"); | ||||||
|  |                 String tableComment = tablesResult.getString("REMARKS"); | ||||||
|  |                 TableCondition tableCondition = TableCondition.of(condition, tableName); | ||||||
|  |                 TableMeta tableMeta = TableMeta.builder() | ||||||
|  |                         .tableName(tableName) | ||||||
|  |                         .tableType(tableType) | ||||||
|  |                         .tableComment(tableComment) | ||||||
|  |                         .columns(columnMetaRepository.selectColumns(connection, tableCondition)) | ||||||
|  |                         .indexes(indexMetaRepository.selectIndexes(connection, tableCondition)) | ||||||
|  |                         .triggers(triggerMetaRepository.selectTriggers(connection, tableCondition)) | ||||||
|  |                         .build(); | ||||||
|  |                 tableMetas.add(tableMeta); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return tableMetas; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | package com.databasir.core.meta.repository.impl.jdbc; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.TriggerMeta; | ||||||
|  | import com.databasir.core.meta.repository.TriggerMetaRepository; | ||||||
|  | import com.databasir.core.meta.repository.condition.TableCondition; | ||||||
|  |  | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public class JdbcTriggerMetaRepository implements TriggerMetaRepository { | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<TriggerMeta> selectTriggers(Connection connection, TableCondition condition) { | ||||||
|  |         // note: jdbc not support get triggers | ||||||
|  |         return Collections.emptyList(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								core/src/main/java/com/databasir/core/render/Render.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								core/src/main/java/com/databasir/core/render/Render.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | package com.databasir.core.render; | ||||||
|  |  | ||||||
|  | import com.databasir.core.meta.pojo.DatabaseMeta; | ||||||
|  | import com.databasir.core.render.markdown.MarkdownRender; | ||||||
|  |  | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.OutputStream; | ||||||
|  |  | ||||||
|  | public interface Render { | ||||||
|  |  | ||||||
|  |     void rendering(DatabaseMeta meta, OutputStream outputStream) throws IOException; | ||||||
|  |  | ||||||
|  |     static Render markdownRender(RenderConfig configuration) { | ||||||
|  |         return MarkdownRender.of(configuration); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,8 +1,8 @@ | |||||||
| package com.databasir.core.doc.render; | package com.databasir.core.render; | ||||||
| 
 | 
 | ||||||
| import com.databasir.core.doc.model.ColumnDoc; | import com.databasir.core.meta.pojo.ColumnMeta; | ||||||
| import com.databasir.core.doc.model.IndexDoc; | import com.databasir.core.meta.pojo.IndexMeta; | ||||||
| import com.databasir.core.doc.model.TriggerDoc; | import com.databasir.core.meta.pojo.TriggerMeta; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| 
 | 
 | ||||||
| import java.util.LinkedHashMap; | import java.util.LinkedHashMap; | ||||||
| @@ -19,15 +19,15 @@ public class RenderConfig { | |||||||
| 
 | 
 | ||||||
|     private Boolean renderTriggers = true; |     private Boolean renderTriggers = true; | ||||||
| 
 | 
 | ||||||
|     private LinkedHashMap<String, Function<ColumnDoc, String>> columnTitleAndValueMapping = columnTitleAndValueMapping(); |     private LinkedHashMap<String, Function<ColumnMeta, String>> columnTitleAndValueMapping = columnTitleAndValueMapping(); | ||||||
| 
 | 
 | ||||||
|     private LinkedHashMap<String, Function<IndexDoc, String>> indexTitleAndValueMapping = indexTitleAndValueMapping(); |     private LinkedHashMap<String, Function<IndexMeta, String>> indexTitleAndValueMapping = indexTitleAndValueMapping(); | ||||||
| 
 | 
 | ||||||
|     private LinkedHashMap<String, Function<TriggerDoc, String>> triggerTitleAndValueMapping = triggerTitleAndValueMapping(); |     private LinkedHashMap<String, Function<TriggerMeta, String>> triggerTitleAndValueMapping = triggerTitleAndValueMapping(); | ||||||
| 
 | 
 | ||||||
|     protected LinkedHashMap<String, Function<ColumnDoc, String>> columnTitleAndValueMapping() { |     protected LinkedHashMap<String, Function<ColumnMeta, String>> columnTitleAndValueMapping() { | ||||||
|         LinkedHashMap<String, Function<ColumnDoc, String>> mapping = new LinkedHashMap<>(); |         LinkedHashMap<String, Function<ColumnMeta, String>> mapping = new LinkedHashMap<>(); | ||||||
|         mapping.put("Name", ColumnDoc::getName); |         mapping.put("Name", ColumnMeta::getName); | ||||||
|         mapping.put("Type", column -> { |         mapping.put("Type", column -> { | ||||||
|             String type; |             String type; | ||||||
|             if (column.getDecimalDigits() == null || column.getDecimalDigits().equals(0)) { |             if (column.getDecimalDigits() == null || column.getDecimalDigits().equals(0)) { | ||||||
| @@ -50,26 +50,26 @@ public class RenderConfig { | |||||||
|             } |             } | ||||||
|             return column.getDefaultValue(); |             return column.getDefaultValue(); | ||||||
|         }); |         }); | ||||||
|         mapping.put("Comment", ColumnDoc::getComment); |         mapping.put("Comment", ColumnMeta::getComment); | ||||||
|         return mapping; |         return mapping; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected LinkedHashMap<String, Function<IndexDoc, String>> indexTitleAndValueMapping() { |     protected LinkedHashMap<String, Function<IndexMeta, String>> indexTitleAndValueMapping() { | ||||||
|         LinkedHashMap<String, Function<IndexDoc, String>> mapping = new LinkedHashMap<>(); |         LinkedHashMap<String, Function<IndexMeta, String>> mapping = new LinkedHashMap<>(); | ||||||
|         mapping.put("Name", IndexDoc::getIndexName); |         mapping.put("Name", IndexMeta::getIndexName); | ||||||
|         mapping.put("IsPrimary", index -> index.getIsPrimaryKey() ? "YES" : ""); |         mapping.put("IsPrimary", index -> index.getIsPrimaryKey() ? "YES" : ""); | ||||||
|         mapping.put("IsUnique", index -> index.getIsUniqueKey() ? "YES" : ""); |         mapping.put("IsUnique", index -> index.getIsUniqueKey() ? "YES" : ""); | ||||||
|         mapping.put("Columns", index -> String.join(", ", index.getColumnNames())); |         mapping.put("Columns", index -> String.join(", ", index.getColumnNames())); | ||||||
|         return mapping; |         return mapping; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected LinkedHashMap<String, Function<TriggerDoc, String>> triggerTitleAndValueMapping() { |     protected LinkedHashMap<String, Function<TriggerMeta, String>> triggerTitleAndValueMapping() { | ||||||
|         LinkedHashMap<String, Function<TriggerDoc, String>> mapping = new LinkedHashMap<>(); |         LinkedHashMap<String, Function<TriggerMeta, String>> mapping = new LinkedHashMap<>(); | ||||||
|         mapping.put("Name", TriggerDoc::getName); |         mapping.put("Name", TriggerMeta::getName); | ||||||
|         mapping.put("Timing", trigger -> trigger.getTiming() + " " + trigger.getManipulation()); |         mapping.put("Timing", trigger -> trigger.getTiming() + " " + trigger.getManipulation()); | ||||||
|         mapping.put("Statement", trigger -> trigger.getStatement().replace("\n", " ") |         mapping.put("Statement", trigger -> trigger.getStatement().replace("\n", " ") | ||||||
|                 .replace("\r", " ")); |                 .replace("\r", " ")); | ||||||
|         mapping.put("Create At", TriggerDoc::getCreateAt); |         mapping.put("Create At", TriggerMeta::getCreateAt); | ||||||
|         return mapping; |         return mapping; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| package com.databasir.core.doc.render.markdown; | package com.databasir.core.render.markdown; | ||||||
| 
 | 
 | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| @@ -1,15 +1,17 @@ | |||||||
| package com.databasir.core.doc.render.markdown; | package com.databasir.core.render.markdown; | ||||||
| 
 | 
 | ||||||
| import com.databasir.core.doc.model.DatabaseDoc; | import com.databasir.core.meta.pojo.DatabaseMeta; | ||||||
| import com.databasir.core.doc.model.TableDoc; | import com.databasir.core.meta.pojo.TableMeta; | ||||||
| import com.databasir.core.doc.render.Render; | import com.databasir.core.render.Render; | ||||||
| import com.databasir.core.doc.render.RenderConfig; | import com.databasir.core.render.RenderConfig; | ||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
| 
 | 
 | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.OutputStream; | import java.io.OutputStream; | ||||||
| import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||||
| import java.util.*; | import java.util.ArrayList; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.List; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| 
 | 
 | ||||||
| public class MarkdownRender implements Render { | public class MarkdownRender implements Render { | ||||||
| @@ -26,12 +28,12 @@ public class MarkdownRender implements Render { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void rendering(DatabaseDoc doc, |     public void rendering(DatabaseMeta meta, | ||||||
|                           OutputStream outputStream) throws IOException { |                           OutputStream outputStream) throws IOException { | ||||||
|         MarkdownBuilder contentBuilder = MarkdownBuilder.builder(); |         MarkdownBuilder contentBuilder = MarkdownBuilder.builder(); | ||||||
|         contentBuilder.primaryTitle(doc.getDatabaseName()); |         contentBuilder.primaryTitle(meta.getDatabaseName()); | ||||||
|         if (config.getRenderTables()) { |         if (config.getRenderTables()) { | ||||||
|             for (TableDoc table : doc.getTables()) { |             for (TableMeta table : meta.getTables()) { | ||||||
|                 buildTableName(contentBuilder, table); |                 buildTableName(contentBuilder, table); | ||||||
|                 if (config.getRenderColumns()) { |                 if (config.getRenderColumns()) { | ||||||
|                     buildColumns(contentBuilder, table); |                     buildColumns(contentBuilder, table); | ||||||
| @@ -47,7 +49,7 @@ public class MarkdownRender implements Render { | |||||||
|         outputStream.write(contentBuilder.build().getBytes(StandardCharsets.UTF_8)); |         outputStream.write(contentBuilder.build().getBytes(StandardCharsets.UTF_8)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void buildTableName(MarkdownBuilder contentBuilder, TableDoc table) { |     private void buildTableName(MarkdownBuilder contentBuilder, TableMeta table) { | ||||||
|         String tableName; |         String tableName; | ||||||
|         if (table.getTableComment() == null || table.getTableComment().trim().isEmpty()) { |         if (table.getTableComment() == null || table.getTableComment().trim().isEmpty()) { | ||||||
|             tableName = table.getTableName(); |             tableName = table.getTableName(); | ||||||
| @@ -57,7 +59,7 @@ public class MarkdownRender implements Render { | |||||||
|         contentBuilder.secondTitle(tableName); |         contentBuilder.secondTitle(tableName); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void buildColumns(MarkdownBuilder contentBuilder, TableDoc table) { |     private void buildColumns(MarkdownBuilder contentBuilder, TableMeta table) { | ||||||
|         contentBuilder.unorderedList(Collections.singletonList("columns")); |         contentBuilder.unorderedList(Collections.singletonList("columns")); | ||||||
|         List<List<String>> allColumnRows = table.getColumns() |         List<List<String>> allColumnRows = table.getColumns() | ||||||
|                 .stream() |                 .stream() | ||||||
| @@ -70,7 +72,7 @@ public class MarkdownRender implements Render { | |||||||
|         contentBuilder.table(tableTitles(), allColumnRows); |         contentBuilder.table(tableTitles(), allColumnRows); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void buildIndexes(MarkdownBuilder contentBuilder, TableDoc table) { |     private void buildIndexes(MarkdownBuilder contentBuilder, TableMeta table) { | ||||||
|         contentBuilder.unorderedList(Collections.singletonList("indexes")); |         contentBuilder.unorderedList(Collections.singletonList("indexes")); | ||||||
|         List<List<String>> allIndexRows = table.getIndexes().stream() |         List<List<String>> allIndexRows = table.getIndexes().stream() | ||||||
|                 .map(index -> config.getIndexTitleAndValueMapping() |                 .map(index -> config.getIndexTitleAndValueMapping() | ||||||
| @@ -82,7 +84,7 @@ public class MarkdownRender implements Render { | |||||||
|         contentBuilder.table(indexTitles(), allIndexRows); |         contentBuilder.table(indexTitles(), allIndexRows); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void buildTriggers(MarkdownBuilder contentBuilder, TableDoc table) { |     private void buildTriggers(MarkdownBuilder contentBuilder, TableMeta table) { | ||||||
|         if (table.getTriggers() == null || table.getTriggers().isEmpty()) { |         if (table.getTriggers() == null || table.getTriggers().isEmpty()) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @@ -1,43 +1,36 @@ | |||||||
| import com.databasir.core.doc.factory.DatabaseDocConfig; | import com.databasir.core.Databasir; | ||||||
| import com.databasir.core.doc.factory.extension.mysql.MysqlTableTriggerDocFactory; | import com.databasir.core.meta.pojo.DatabaseMeta; | ||||||
| import com.databasir.core.doc.factory.jdbc.JdbcDatabaseDocFactory; |  | ||||||
| import com.databasir.core.doc.model.DatabaseDoc; |  | ||||||
| import com.databasir.core.doc.render.Render; |  | ||||||
| import com.databasir.core.doc.render.RenderConfig; |  | ||||||
|  |  | ||||||
| import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
|  | import java.sql.Connection; | ||||||
| import java.sql.DriverManager; | import java.sql.DriverManager; | ||||||
| import java.sql.SQLException; | import java.sql.SQLException; | ||||||
| import java.util.Properties; | import java.util.Properties; | ||||||
|  |  | ||||||
| public class App { | public class App { | ||||||
|     public static void main(String[] args) throws SQLException, ClassNotFoundException { |     public static void main(String[] args) throws SQLException, ClassNotFoundException { | ||||||
|  |         try (FileOutputStream out = new FileOutputStream("user.md")) { | ||||||
|  |             Connection connection = getJdbcConnection(); | ||||||
|  |             Databasir databasir = Databasir.of(); | ||||||
|  |             DatabaseMeta doc = databasir.get(connection, "user").orElseThrow(); | ||||||
|  |             databasir.renderAsMarkdown(doc, out); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             throw new IllegalStateException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static Connection getJdbcConnection() throws SQLException, ClassNotFoundException { | ||||||
|         // get database connection |         // get database connection | ||||||
|         Class.forName("com.mysql.cj.jdbc.Driver"); |         Class.forName("com.mysql.cj.jdbc.Driver"); | ||||||
|  |  | ||||||
|         Properties info = new Properties(); |         Properties info = new Properties(); | ||||||
|         info.put("user", "root"); |         info.put("user", "root"); | ||||||
|         info.put("password", "123456"); |         info.put("password", "123456"); | ||||||
|         // this config is used by mysql |         // this config is used by mysql | ||||||
|         info.put("useInformationSchema", "true"); |         info.put("useInformationSchema", "true"); | ||||||
|  |  | ||||||
|         String url = "jdbc:mysql://localhost:3306/patient?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true"; |         String url = "jdbc:mysql://localhost:3306/patient?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true"; | ||||||
|         var connection = DriverManager.getConnection(url, info); |         return DriverManager.getConnection(url, info); | ||||||
|  |  | ||||||
|         // generate doc model |  | ||||||
|         var config = DatabaseDocConfig.builder() |  | ||||||
|                 .databaseName("user") |  | ||||||
|                 .connection(connection) |  | ||||||
|                 .tableTriggerDocFactory(new MysqlTableTriggerDocFactory()) |  | ||||||
|                 .build(); |  | ||||||
|         DatabaseDoc doc = JdbcDatabaseDocFactory.of().create(config).orElseThrow(); |  | ||||||
|  |  | ||||||
|         // render as markdown |  | ||||||
|         try (FileOutputStream out = new FileOutputStream("user.md")) { |  | ||||||
|             RenderConfig renderConfig = new RenderConfig(); |  | ||||||
|             renderConfig.setRenderTriggers(true); |  | ||||||
|             Render.markdownRender(renderConfig).rendering(doc, out); |  | ||||||
|         } catch (IOException e) { |  | ||||||
|             throw new IllegalStateException(e); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user