diff --git a/README.md b/README.md index d1f2301..d5a7d4e 100644 --- a/README.md +++ b/README.md @@ -9,31 +9,24 @@ you could use `databasir` to generate database meta model, or render it as markd ## Database Meta to Java Model ```java -java.sql.Connection connection = ...; -DatabaseDocConfig config = DatabaseDocConfig.builder() - .databaseName("Demo") - .connection(connection) - .build(); -DatabaseDoc doc = JdbcDatabaseDocFactory.of().create(config).orElseThrow(); +java.sql.Connection connection=...; + DatabaseMeta meta=Databasir.of().get(connection,"user").orElseThrow(); ``` ## Render as Markdown + ```java -java.sql.Connection connection = ...; -DatabaseDocConfig config = DatabaseDocConfig.builder() - .databaseName("Demo") - .connection(connection) - .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) { - throw new IllegalStateException(e); -} +try(FileOutputStream out=new FileOutputStream("user.md")){ + java.sql.Connection connection=...; + Databasir databasir=Databasir.of(); + DatabaseMeta meta=databasir.get(connection,"user").orElseThrow(); + databasir.renderAsMarkdown(doc,out); + }catch(IOException e){ + throw new IllegalStateException(e); + } ``` -- Example +- Markdown Example ![](README/table-doc.png) @@ -43,37 +36,32 @@ try (FileOutputStream out = new FileOutputStream("doc.md")) { support regex pattern to ignore table or column ```java -java.sql.Connection connection = ...; -DatabaseDocConfig config = DatabaseDocConfig.builder() - .databaseName("Demo") - .connection(connection) - .ignoreTableRegexes(Arrays.asList("mysql_*")) - .ignoreColumnRegexes(Arrays.asList("id")) - .build(); -DatabaseDoc doc = JdbcDatabaseDocFactory.of().create(config).orElseThrow(); +java.sql.Connection connection=...; + DatabasirConfig config=new DatabasirConfig(); + config.ignoreColumn("id*"); + config.ignoreTable("flyway.*"); + DatabaseMeta meta=Databasir.of(config).get(connection,"user").orElseThrow(); ``` ## 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 + ```java -java.sql.Connection connection = ...; -DatabaseDocConfig config = DatabaseDocConfig.builder() - .databaseName("Demo") - .connection(connection) - .tableDocFactory(...) // your custom table doc factory - .tableColumnDocFactory(...) // your custom column doc factory - .tableIndexDocFactory(...) // your custom index doc factory - .tableTriggerDocFactory(...) // your custom trigger doc factory - .build(); -DatabaseDoc doc = JdbcDatabaseDocFactory.of().create(config).orElseThrow(); +java.sql.Connection connection=...; + DatabasirConfig config=new DatabasirConfig(); + config.setDatabaseMetaRepository(...); // your custom repository + config.setTableMetaRepository(...); // your custom repository + config.setColumnMetaRepository(...); // your custom repository + config.setTriggerMetaRepository(...); // your custom repository + config.setIndexMetaRepository(...); // your custom repository + DatabaseMeta meta=Databasir.of().get(connection,"user").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 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 74981ab..3b22ba6 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ subprojects { apply plugin: 'java' - group 'cc.cc1234' + group 'com.databasir' version '1.0-SNAPSHOT' repositories { diff --git a/core/src/main/java/com/databasir/core/Databasir.java b/core/src/main/java/com/databasir/core/Databasir.java new file mode 100644 index 0000000..13a1ea4 --- /dev/null +++ b/core/src/main/java/com/databasir/core/Databasir.java @@ -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 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); + } + +} diff --git a/core/src/main/java/com/databasir/core/DatabasirConfig.java b/core/src/main/java/com/databasir/core/DatabasirConfig.java new file mode 100644 index 0000000..226bbbf --- /dev/null +++ b/core/src/main/java/com/databasir/core/DatabasirConfig.java @@ -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 ignoreTableNameRegex = new HashSet<>(); + + private Collection ignoreTableColumnNameRegex = new HashSet<>(); + + public DatabasirConfig ignoreTable(String tableNameRegex) { + ignoreTableNameRegex.add(tableNameRegex); + return this; + } + + public DatabasirConfig ignoreColumn(String columnNameRegex) { + ignoreTableColumnNameRegex.add(columnNameRegex); + return this; + } +} diff --git a/core/src/main/java/com/databasir/core/doc/factory/DatabaseDocConfig.java b/core/src/main/java/com/databasir/core/doc/factory/DatabaseDocConfig.java deleted file mode 100644 index 3afb89f..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/DatabaseDocConfig.java +++ /dev/null @@ -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 ignoreTableRegexes = Collections.emptyList(); - - @Builder.Default - private List 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)); - } - -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/DatabaseDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/DatabaseDocFactory.java deleted file mode 100644 index de59447..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/DatabaseDocFactory.java +++ /dev/null @@ -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 { - - Optional create(DatabaseDocConfig configuration); - -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/Sortable.java b/core/src/main/java/com/databasir/core/doc/factory/Sortable.java deleted file mode 100644 index 4d8e4db..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/Sortable.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.databasir.core.doc.factory; - -public interface Sortable> extends Comparable { - - /** - * @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()); - } -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/TableColumnDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/TableColumnDocFactory.java deleted file mode 100644 index 3401eb6..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/TableColumnDocFactory.java +++ /dev/null @@ -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 { - - List create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration); - -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/TableDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/TableDocFactory.java deleted file mode 100644 index f4fb135..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/TableDocFactory.java +++ /dev/null @@ -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 { - - List create(DatabaseMetaData metaData, DatabaseDocConfig configuration); - -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/TableIndexDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/TableIndexDocFactory.java deleted file mode 100644 index 68f7a1e..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/TableIndexDocFactory.java +++ /dev/null @@ -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 { - - List create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration); - -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/TableTriggerDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/TableTriggerDocFactory.java deleted file mode 100644 index a0faaa9..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/TableTriggerDocFactory.java +++ /dev/null @@ -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 { - - List create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration); -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcDatabaseDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcDatabaseDocFactory.java deleted file mode 100644 index 2c5cb5a..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcDatabaseDocFactory.java +++ /dev/null @@ -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 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 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); - } - } -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableDocFactory.java deleted file mode 100644 index ce74f50..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableDocFactory.java +++ /dev/null @@ -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 create(DatabaseMetaData metaData, - DatabaseDocConfig configuration) { - try { - return doCreateTableDoc(metaData, configuration); - } catch (SQLException e) { - throw new IllegalStateException(e); - } - } - - private List doCreateTableDoc(DatabaseMetaData metaData, - DatabaseDocConfig configuration) throws SQLException { - List 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; - } - -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableIndexDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableIndexDocFactory.java deleted file mode 100644 index 3c615d3..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableIndexDocFactory.java +++ /dev/null @@ -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 create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration) { - try { - return doCreateIndexDocs(tableName, metaData, configuration); - } catch (SQLException e) { - throw new IllegalStateException(e); - } - } - - private List doCreateIndexDocs(String tableName, - DatabaseMetaData metaData, - DatabaseDocConfig configuration) - throws SQLException { - List 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 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 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()); - } - -} diff --git a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableTriggerDocFactory.java b/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableTriggerDocFactory.java deleted file mode 100644 index 25ec97c..0000000 --- a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableTriggerDocFactory.java +++ /dev/null @@ -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 create(String tableName, DatabaseMetaData metaData, DatabaseDocConfig configuration) { - // note: jdbc not support get triggers - return Collections.emptyList(); - } -} diff --git a/core/src/main/java/com/databasir/core/doc/render/Render.java b/core/src/main/java/com/databasir/core/doc/render/Render.java deleted file mode 100644 index 21a41ab..0000000 --- a/core/src/main/java/com/databasir/core/doc/render/Render.java +++ /dev/null @@ -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); - } -} diff --git a/core/src/main/java/com/databasir/core/doc/render/pdf/.gitkeep b/core/src/main/java/com/databasir/core/doc/render/pdf/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/core/src/main/java/com/databasir/core/doc/model/ColumnDoc.java b/core/src/main/java/com/databasir/core/meta/pojo/ColumnMeta.java similarity index 82% rename from core/src/main/java/com/databasir/core/doc/model/ColumnDoc.java rename to core/src/main/java/com/databasir/core/meta/pojo/ColumnMeta.java index 96df982..6535eef 100644 --- a/core/src/main/java/com/databasir/core/doc/model/ColumnDoc.java +++ b/core/src/main/java/com/databasir/core/meta/pojo/ColumnMeta.java @@ -1,11 +1,11 @@ -package com.databasir.core.doc.model; +package com.databasir.core.meta.pojo; import lombok.Builder; import lombok.Data; @Data @Builder -public class ColumnDoc { +public class ColumnMeta { private String name; diff --git a/core/src/main/java/com/databasir/core/doc/model/DatabaseDoc.java b/core/src/main/java/com/databasir/core/meta/pojo/DatabaseMeta.java similarity index 51% rename from core/src/main/java/com/databasir/core/doc/model/DatabaseDoc.java rename to core/src/main/java/com/databasir/core/meta/pojo/DatabaseMeta.java index 00a029b..b43455d 100644 --- a/core/src/main/java/com/databasir/core/doc/model/DatabaseDoc.java +++ b/core/src/main/java/com/databasir/core/meta/pojo/DatabaseMeta.java @@ -1,4 +1,4 @@ -package com.databasir.core.doc.model; +package com.databasir.core.meta.pojo; import lombok.Builder; import lombok.Data; @@ -8,21 +8,36 @@ import java.util.List; @Data @Builder -public class DatabaseDoc { +public class DatabaseMeta { + /** + * product_name + */ private String productName; + /** + * product_version + */ private String productVersion; + /** + * driver_name + */ private String driverName; + /** + * driver_version + */ private String driverVersion; + /** + * database_name + */ private String databaseName; private String remark; @Builder.Default - private List tables = Collections.emptyList(); + private List tables = Collections.emptyList(); } diff --git a/core/src/main/java/com/databasir/core/doc/model/IndexDoc.java b/core/src/main/java/com/databasir/core/meta/pojo/IndexMeta.java similarity index 82% rename from core/src/main/java/com/databasir/core/doc/model/IndexDoc.java rename to core/src/main/java/com/databasir/core/meta/pojo/IndexMeta.java index 5097234..c878555 100644 --- a/core/src/main/java/com/databasir/core/doc/model/IndexDoc.java +++ b/core/src/main/java/com/databasir/core/meta/pojo/IndexMeta.java @@ -1,4 +1,4 @@ -package com.databasir.core.doc.model; +package com.databasir.core.meta.pojo; import lombok.Builder; import lombok.Data; @@ -8,7 +8,7 @@ import java.util.List; @Data @Builder -public class IndexDoc { +public class IndexMeta { private String indexName; diff --git a/core/src/main/java/com/databasir/core/doc/model/TableDoc.java b/core/src/main/java/com/databasir/core/meta/pojo/TableMeta.java similarity index 54% rename from core/src/main/java/com/databasir/core/doc/model/TableDoc.java rename to core/src/main/java/com/databasir/core/meta/pojo/TableMeta.java index 58c8617..b98ff2d 100644 --- a/core/src/main/java/com/databasir/core/doc/model/TableDoc.java +++ b/core/src/main/java/com/databasir/core/meta/pojo/TableMeta.java @@ -1,4 +1,4 @@ -package com.databasir.core.doc.model; +package com.databasir.core.meta.pojo; import lombok.Builder; import lombok.Data; @@ -8,7 +8,7 @@ import java.util.List; @Data @Builder -public class TableDoc { +public class TableMeta { private String tableName; @@ -17,13 +17,13 @@ public class TableDoc { private String tableComment; @Builder.Default - private List columns = Collections.emptyList(); + private List columns = Collections.emptyList(); @Builder.Default - private List triggers = Collections.emptyList(); + private List triggers = Collections.emptyList(); @Builder.Default - private List indexes = Collections.emptyList(); + private List indexes = Collections.emptyList(); private String remark; } diff --git a/core/src/main/java/com/databasir/core/doc/model/TriggerDoc.java b/core/src/main/java/com/databasir/core/meta/pojo/TriggerMeta.java similarity index 84% rename from core/src/main/java/com/databasir/core/doc/model/TriggerDoc.java rename to core/src/main/java/com/databasir/core/meta/pojo/TriggerMeta.java index 32a64ae..a67061f 100644 --- a/core/src/main/java/com/databasir/core/doc/model/TriggerDoc.java +++ b/core/src/main/java/com/databasir/core/meta/pojo/TriggerMeta.java @@ -1,4 +1,4 @@ -package com.databasir.core.doc.model; +package com.databasir.core.meta.pojo; import lombok.Builder; import lombok.Data; @@ -8,7 +8,7 @@ import lombok.Data; */ @Data @Builder -public class TriggerDoc { +public class TriggerMeta { private String name; diff --git a/core/src/main/java/com/databasir/core/meta/provider/SqlProvider.java b/core/src/main/java/com/databasir/core/meta/provider/SqlProvider.java new file mode 100644 index 0000000..16b8a60 --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/provider/SqlProvider.java @@ -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(); + + /** + *

+ * generate sql to select database information, should return the follow columns + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
column name column type description nullable
TABLE_CAT String catalog name NO
+ *
+ * + * @param databaseName + * @return + */ + default Optional databaseMetaSql(String databaseName) { + return Optional.empty(); + } + + /** + * generate sql to select table information, should return the follow columns + * + * + * + * + * + * + * + * + * + * + * + * + * + *
column name column type description nullable
TABLE_CAT String catalog name NO
+ * + * @param databaseName + * @param tableName + * @return + */ + default Optional tableMetaSql(String databaseName, String tableName) { + return Optional.empty(); + } + + default Optional tableColumnMetaSql(String databaseName, String tableName) { + return Optional.empty(); + } + + default Optional tableIndexMetaSql(String databaseName, String tableName) { + return Optional.empty(); + } + + default Optional tableTriggerMetaSql(String databaseName, String tableName) { + return Optional.empty(); + } + + class Default implements SqlProvider { + + } +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/ColumnMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/ColumnMetaRepository.java new file mode 100644 index 0000000..b907998 --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/ColumnMetaRepository.java @@ -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 selectColumns(Connection connection, TableCondition condition); + +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/DatabaseMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/DatabaseMetaRepository.java new file mode 100644 index 0000000..962786d --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/DatabaseMetaRepository.java @@ -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 select(Connection connection, Condition condition); + +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/IndexMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/IndexMetaRepository.java new file mode 100644 index 0000000..72a9e24 --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/IndexMetaRepository.java @@ -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 selectIndexes(Connection connection, TableCondition condition); +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/TableMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/TableMetaRepository.java new file mode 100644 index 0000000..e52f54e --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/TableMetaRepository.java @@ -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 selectTables(Connection connection, Condition condition); + +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/TriggerMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/TriggerMetaRepository.java new file mode 100644 index 0000000..b14c054 --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/TriggerMetaRepository.java @@ -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 selectTriggers(Connection connection, TableCondition condition); + +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/condition/Condition.java b/core/src/main/java/com/databasir/core/meta/repository/condition/Condition.java new file mode 100644 index 0000000..9e83edb --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/condition/Condition.java @@ -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 ignoreTableNameRegex = Collections.emptyList(); + + @Builder.Default + private Collection 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)); + } +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/condition/TableCondition.java b/core/src/main/java/com/databasir/core/meta/repository/condition/TableCondition.java new file mode 100644 index 0000000..2d601ec --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/condition/TableCondition.java @@ -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(); + } + + +} diff --git a/core/src/main/java/com/databasir/core/doc/factory/extension/mysql/MysqlTableTriggerDocFactory.java b/core/src/main/java/com/databasir/core/meta/repository/impl/extension/MysqlTableTriggerMetaRepository.java similarity index 70% rename from core/src/main/java/com/databasir/core/doc/factory/extension/mysql/MysqlTableTriggerDocFactory.java rename to core/src/main/java/com/databasir/core/meta/repository/impl/extension/MysqlTableTriggerMetaRepository.java index 703724d..7c3a764 100644 --- a/core/src/main/java/com/databasir/core/doc/factory/extension/mysql/MysqlTableTriggerDocFactory.java +++ b/core/src/main/java/com/databasir/core/meta/repository/impl/extension/MysqlTableTriggerMetaRepository.java @@ -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.doc.factory.TableTriggerDocFactory; -import com.databasir.core.doc.model.TriggerDoc; +import com.databasir.core.meta.pojo.TriggerMeta; +import com.databasir.core.meta.repository.TriggerMetaRepository; +import com.databasir.core.meta.repository.condition.TableCondition; import lombok.extern.slf4j.Slf4j; -import java.sql.DatabaseMetaData; +import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -14,12 +14,10 @@ import java.util.Collections; import java.util.List; @Slf4j -public class MysqlTableTriggerDocFactory implements TableTriggerDocFactory { +public class MysqlTableTriggerMetaRepository implements TriggerMetaRepository { @Override - public List create(String tableName, - DatabaseMetaData metaData, - DatabaseDocConfig configuration) { + public List selectTriggers(Connection connection, TableCondition condition) { String sql = "SELECT TRIGGER_CATALOG,\n" + " TRIGGER_SCHEMA,\n" + " TRIGGER_NAME,\n" + @@ -41,26 +39,25 @@ public class MysqlTableTriggerDocFactory implements TableTriggerDocFactory { " DEFINER\n " + "FROM information_schema.TRIGGERS WHERE EVENT_OBJECT_SCHEMA = ? AND EVENT_OBJECT_TABLE = ?"; try { - PreparedStatement preparedStatement = configuration.getConnection() - .prepareStatement(sql); - preparedStatement.setObject(1, configuration.getDatabaseName()); - preparedStatement.setObject(2, tableName); + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setObject(1, condition.getDatabaseName()); + preparedStatement.setObject(2, condition.getTableName()); ResultSet results = preparedStatement.executeQuery(); - List triggers = new ArrayList<>(); + List triggers = new ArrayList<>(); while (results.next()) { String name = results.getString("TRIGGER_NAME"); String statement = results.getString("ACTION_STATEMENT"); String timing = results.getString("ACTION_TIMING"); String manipulation = results.getString("EVENT_MANIPULATION"); String created = results.getString("CREATED"); - TriggerDoc doc = TriggerDoc.builder() + TriggerMeta meta = TriggerMeta.builder() .name(name) .manipulation(manipulation) .timing(timing) .statement(statement) .createAt(created) .build(); - triggers.add(doc); + triggers.add(meta); } return triggers; } catch (SQLException e) { diff --git a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableColumnDocFactory.java b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcColumnMetaRepository.java similarity index 59% rename from core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableColumnDocFactory.java rename to core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcColumnMetaRepository.java index bbdc3d8..1795554 100644 --- a/core/src/main/java/com/databasir/core/doc/factory/jdbc/JdbcTableColumnDocFactory.java +++ b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcColumnMetaRepository.java @@ -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.doc.factory.TableColumnDocFactory; -import com.databasir.core.doc.model.ColumnDoc; +import com.databasir.core.meta.pojo.ColumnMeta; +import com.databasir.core.meta.repository.ColumnMetaRepository; +import com.databasir.core.meta.repository.condition.TableCondition; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import java.sql.DatabaseMetaData; +import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; @@ -13,34 +14,32 @@ import java.util.List; import java.util.Objects; @Slf4j -public class JdbcTableColumnDocFactory implements TableColumnDocFactory { +@RequiredArgsConstructor +public class JdbcColumnMetaRepository implements ColumnMetaRepository { @Override - public List create(String tableName, - DatabaseMetaData metaData, - DatabaseDocConfig configuration) { + public List selectColumns(Connection connection, TableCondition tableCondition) { try { - return doCreate(tableName, metaData, configuration); + return doSelect(connection, tableCondition); } catch (SQLException e) { throw new IllegalStateException(e); } } - private List doCreate(String tableName, - DatabaseMetaData metaData, - DatabaseDocConfig configuration) throws SQLException { - List columnDocs = new ArrayList<>(); - String database = configuration.getDatabaseName(); + private List doSelect(Connection connection, TableCondition tableCondition) throws SQLException { + List columnDocs = new ArrayList<>(); + String databaseName = tableCondition.getDatabaseName(); + String tableName = tableCondition.getTableName(); ResultSet columnsResult; try { - columnsResult = metaData.getColumns(database, null, tableName, null); + columnsResult = connection.getMetaData().getColumns(databaseName, null, tableName, null); } catch (SQLException e) { - log.warn("warn: ignore columns in " + database + "." + tableName); + log.warn("warn: ignore columns in " + databaseName + "." + tableName); return columnDocs; } while (columnsResult.next()) { String columnName = columnsResult.getString("COLUMN_NAME"); - if (configuration.columnIsIgnored(columnName)) { + if (tableCondition.columnIsIgnored(columnName)) { if (log.isWarnEnabled()) { log.warn("ignore column: " + columnName); } @@ -52,7 +51,7 @@ public class JdbcTableColumnDocFactory implements TableColumnDocFactory { boolean isNullable = Objects.equals("YES", columnsResult.getString("IS_NULLABLE")); boolean isAutoIncrement = Objects.equals("YES", columnsResult.getString("IS_AUTOINCREMENT")); String columnComment = columnsResult.getString("REMARKS"); - ColumnDoc columnDoc = ColumnDoc.builder() + ColumnMeta columnMeta = ColumnMeta.builder() .name(columnName) .type(columnType) .size(columnSize) @@ -62,11 +61,10 @@ public class JdbcTableColumnDocFactory implements TableColumnDocFactory { .comment(columnComment) .defaultValue(defaultValue) .build(); - columnDocs.add(columnDoc); + columnDocs.add(columnMeta); } } return columnDocs; } - } diff --git a/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcDatabaseMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcDatabaseMetaRepository.java new file mode 100644 index 0000000..54fb713 --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcDatabaseMetaRepository.java @@ -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 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 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); + } + } + +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcIndexMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcIndexMetaRepository.java new file mode 100644 index 0000000..745657e --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcIndexMetaRepository.java @@ -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 selectIndexes(Connection connection, TableCondition condition) { + try { + return doCreateIndexDocs(connection, condition); + } catch (SQLException e) { + throw new IllegalStateException(e); + } + } + + private List doCreateIndexDocs(Connection connection, TableCondition condition) + throws SQLException { + String databaseName = condition.getDatabaseName(); + String tableName = condition.getTableName(); + List 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 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 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()); + } + +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTableMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTableMetaRepository.java new file mode 100644 index 0000000..2f06d68 --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTableMetaRepository.java @@ -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 selectTables(Connection connection, Condition condition) { + try { + return doSelect(connection, condition); + } catch (SQLException e) { + throw new IllegalStateException(e); + } + } + + private List doSelect(Connection connection, Condition condition) throws SQLException { + List 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; + } + +} diff --git a/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTriggerMetaRepository.java b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTriggerMetaRepository.java new file mode 100644 index 0000000..982e8bd --- /dev/null +++ b/core/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcTriggerMetaRepository.java @@ -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 selectTriggers(Connection connection, TableCondition condition) { + // note: jdbc not support get triggers + return Collections.emptyList(); + } +} diff --git a/core/src/main/java/com/databasir/core/render/Render.java b/core/src/main/java/com/databasir/core/render/Render.java new file mode 100644 index 0000000..d79f9ca --- /dev/null +++ b/core/src/main/java/com/databasir/core/render/Render.java @@ -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); + } +} diff --git a/core/src/main/java/com/databasir/core/doc/render/RenderConfig.java b/core/src/main/java/com/databasir/core/render/RenderConfig.java similarity index 58% rename from core/src/main/java/com/databasir/core/doc/render/RenderConfig.java rename to core/src/main/java/com/databasir/core/render/RenderConfig.java index f39afab..bf26357 100644 --- a/core/src/main/java/com/databasir/core/doc/render/RenderConfig.java +++ b/core/src/main/java/com/databasir/core/render/RenderConfig.java @@ -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.doc.model.IndexDoc; -import com.databasir.core.doc.model.TriggerDoc; +import com.databasir.core.meta.pojo.ColumnMeta; +import com.databasir.core.meta.pojo.IndexMeta; +import com.databasir.core.meta.pojo.TriggerMeta; import lombok.Data; import java.util.LinkedHashMap; @@ -19,15 +19,15 @@ public class RenderConfig { private Boolean renderTriggers = true; - private LinkedHashMap> columnTitleAndValueMapping = columnTitleAndValueMapping(); + private LinkedHashMap> columnTitleAndValueMapping = columnTitleAndValueMapping(); - private LinkedHashMap> indexTitleAndValueMapping = indexTitleAndValueMapping(); + private LinkedHashMap> indexTitleAndValueMapping = indexTitleAndValueMapping(); - private LinkedHashMap> triggerTitleAndValueMapping = triggerTitleAndValueMapping(); + private LinkedHashMap> triggerTitleAndValueMapping = triggerTitleAndValueMapping(); - protected LinkedHashMap> columnTitleAndValueMapping() { - LinkedHashMap> mapping = new LinkedHashMap<>(); - mapping.put("Name", ColumnDoc::getName); + protected LinkedHashMap> columnTitleAndValueMapping() { + LinkedHashMap> mapping = new LinkedHashMap<>(); + mapping.put("Name", ColumnMeta::getName); mapping.put("Type", column -> { String type; if (column.getDecimalDigits() == null || column.getDecimalDigits().equals(0)) { @@ -50,26 +50,26 @@ public class RenderConfig { } return column.getDefaultValue(); }); - mapping.put("Comment", ColumnDoc::getComment); + mapping.put("Comment", ColumnMeta::getComment); return mapping; } - protected LinkedHashMap> indexTitleAndValueMapping() { - LinkedHashMap> mapping = new LinkedHashMap<>(); - mapping.put("Name", IndexDoc::getIndexName); + protected LinkedHashMap> indexTitleAndValueMapping() { + LinkedHashMap> mapping = new LinkedHashMap<>(); + mapping.put("Name", IndexMeta::getIndexName); mapping.put("IsPrimary", index -> index.getIsPrimaryKey() ? "YES" : ""); mapping.put("IsUnique", index -> index.getIsUniqueKey() ? "YES" : ""); mapping.put("Columns", index -> String.join(", ", index.getColumnNames())); return mapping; } - protected LinkedHashMap> triggerTitleAndValueMapping() { - LinkedHashMap> mapping = new LinkedHashMap<>(); - mapping.put("Name", TriggerDoc::getName); + protected LinkedHashMap> triggerTitleAndValueMapping() { + LinkedHashMap> mapping = new LinkedHashMap<>(); + mapping.put("Name", TriggerMeta::getName); mapping.put("Timing", trigger -> trigger.getTiming() + " " + trigger.getManipulation()); mapping.put("Statement", trigger -> trigger.getStatement().replace("\n", " ") .replace("\r", " ")); - mapping.put("Create At", TriggerDoc::getCreateAt); + mapping.put("Create At", TriggerMeta::getCreateAt); return mapping; } } diff --git a/core/src/main/java/com/databasir/core/doc/factory/extension/postgresql/.gitkeep b/core/src/main/java/com/databasir/core/render/html/.gitkeep similarity index 100% rename from core/src/main/java/com/databasir/core/doc/factory/extension/postgresql/.gitkeep rename to core/src/main/java/com/databasir/core/render/html/.gitkeep diff --git a/core/src/main/java/com/databasir/core/doc/render/markdown/MarkdownBuilder.java b/core/src/main/java/com/databasir/core/render/markdown/MarkdownBuilder.java similarity index 98% rename from core/src/main/java/com/databasir/core/doc/render/markdown/MarkdownBuilder.java rename to core/src/main/java/com/databasir/core/render/markdown/MarkdownBuilder.java index 57cdb5b..1c459b4 100644 --- a/core/src/main/java/com/databasir/core/doc/render/markdown/MarkdownBuilder.java +++ b/core/src/main/java/com/databasir/core/render/markdown/MarkdownBuilder.java @@ -1,4 +1,4 @@ -package com.databasir.core.doc.render.markdown; +package com.databasir.core.render.markdown; import java.util.List; diff --git a/core/src/main/java/com/databasir/core/doc/render/markdown/MarkdownRender.java b/core/src/main/java/com/databasir/core/render/markdown/MarkdownRender.java similarity index 87% rename from core/src/main/java/com/databasir/core/doc/render/markdown/MarkdownRender.java rename to core/src/main/java/com/databasir/core/render/markdown/MarkdownRender.java index c62298d..44856f3 100644 --- a/core/src/main/java/com/databasir/core/doc/render/markdown/MarkdownRender.java +++ b/core/src/main/java/com/databasir/core/render/markdown/MarkdownRender.java @@ -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.doc.model.TableDoc; -import com.databasir.core.doc.render.Render; -import com.databasir.core.doc.render.RenderConfig; +import com.databasir.core.meta.pojo.DatabaseMeta; +import com.databasir.core.meta.pojo.TableMeta; +import com.databasir.core.render.Render; +import com.databasir.core.render.RenderConfig; import lombok.Getter; import java.io.IOException; import java.io.OutputStream; 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; public class MarkdownRender implements Render { @@ -26,12 +28,12 @@ public class MarkdownRender implements Render { } @Override - public void rendering(DatabaseDoc doc, + public void rendering(DatabaseMeta meta, OutputStream outputStream) throws IOException { MarkdownBuilder contentBuilder = MarkdownBuilder.builder(); - contentBuilder.primaryTitle(doc.getDatabaseName()); + contentBuilder.primaryTitle(meta.getDatabaseName()); if (config.getRenderTables()) { - for (TableDoc table : doc.getTables()) { + for (TableMeta table : meta.getTables()) { buildTableName(contentBuilder, table); if (config.getRenderColumns()) { buildColumns(contentBuilder, table); @@ -47,7 +49,7 @@ public class MarkdownRender implements Render { outputStream.write(contentBuilder.build().getBytes(StandardCharsets.UTF_8)); } - private void buildTableName(MarkdownBuilder contentBuilder, TableDoc table) { + private void buildTableName(MarkdownBuilder contentBuilder, TableMeta table) { String tableName; if (table.getTableComment() == null || table.getTableComment().trim().isEmpty()) { tableName = table.getTableName(); @@ -57,7 +59,7 @@ public class MarkdownRender implements Render { contentBuilder.secondTitle(tableName); } - private void buildColumns(MarkdownBuilder contentBuilder, TableDoc table) { + private void buildColumns(MarkdownBuilder contentBuilder, TableMeta table) { contentBuilder.unorderedList(Collections.singletonList("columns")); List> allColumnRows = table.getColumns() .stream() @@ -70,7 +72,7 @@ public class MarkdownRender implements Render { contentBuilder.table(tableTitles(), allColumnRows); } - private void buildIndexes(MarkdownBuilder contentBuilder, TableDoc table) { + private void buildIndexes(MarkdownBuilder contentBuilder, TableMeta table) { contentBuilder.unorderedList(Collections.singletonList("indexes")); List> allIndexRows = table.getIndexes().stream() .map(index -> config.getIndexTitleAndValueMapping() @@ -82,7 +84,7 @@ public class MarkdownRender implements Render { 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()) { return; } diff --git a/core/src/main/java/com/databasir/core/doc/render/html/.gitkeep b/core/src/main/java/com/databasir/core/render/pdf/.gitkeep similarity index 100% rename from core/src/main/java/com/databasir/core/doc/render/html/.gitkeep rename to core/src/main/java/com/databasir/core/render/pdf/.gitkeep diff --git a/core/src/test/java/App.java b/core/src/test/java/App.java index 7d6b01d..f06a5a4 100644 --- a/core/src/test/java/App.java +++ b/core/src/test/java/App.java @@ -1,43 +1,36 @@ -import com.databasir.core.doc.factory.DatabaseDocConfig; -import com.databasir.core.doc.factory.extension.mysql.MysqlTableTriggerDocFactory; -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 com.databasir.core.Databasir; +import com.databasir.core.meta.pojo.DatabaseMeta; import java.io.FileOutputStream; import java.io.IOException; +import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; public class App { 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 Class.forName("com.mysql.cj.jdbc.Driver"); + Properties info = new Properties(); info.put("user", "root"); info.put("password", "123456"); // this config is used by mysql info.put("useInformationSchema", "true"); + String url = "jdbc:mysql://localhost:3306/patient?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true"; - var connection = 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); - } + return DriverManager.getConnection(url, info); } }