feature: code redesign
This commit is contained in:
parent
d20a400931
commit
29b9e8e50f
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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue