All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.sinri.keel.mysql.dev.TableRowClassSourceCodeGenerator Maven / Gradle / Ivy

Go to download

A website framework with VERT.X for ex-PHP-ers, exactly Ark Framework Users.

The newest version!
package io.github.sinri.keel.mysql.dev;

import io.github.sinri.keel.facade.async.KeelAsyncKit;
import io.github.sinri.keel.mysql.NamedMySQLConnection;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import io.vertx.sqlclient.SqlConnection;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

import static io.github.sinri.keel.facade.KeelInstance.Keel;
import static io.github.sinri.keel.helper.KeelHelpersInterface.KeelHelpers;

/**
 * @since 3.0.15
 * @since 3.0.18 Finished Technical Preview.
 */
public class TableRowClassSourceCodeGenerator {
    private final SqlConnection sqlConnection;
    private final Set tableSet;
    private final Set excludedTableSet;
    private String schema;

    private boolean provideConstSchema = true;
    private boolean provideConstTable = true;
    private boolean provideConstSchemaAndTable = false;
    private @Nullable String strictEnumPackage = null;
    private @Nullable String envelopePackage = null;

    public TableRowClassSourceCodeGenerator(SqlConnection sqlConnection) {
        this.sqlConnection = sqlConnection;
        this.schema = null;
        this.tableSet = new HashSet<>();
        this.excludedTableSet = new HashSet<>();
    }

    public TableRowClassSourceCodeGenerator(NamedMySQLConnection namedMySQLConnection) {
        this.sqlConnection = namedMySQLConnection.getSqlConnection();
        this.schema = null;
        this.tableSet = new HashSet<>();
        this.excludedTableSet = new HashSet<>();
    }

    public TableRowClassSourceCodeGenerator forSchema(String schema) {
        if (schema == null || schema.isEmpty() || schema.isBlank()) {
            this.schema = null;
        } else {
            this.schema = schema;
        }
        return this;
    }

    public TableRowClassSourceCodeGenerator forTables(Collection tables) {
        this.tableSet.addAll(tables);
        return this;
    }

    public TableRowClassSourceCodeGenerator forTable(String table) {
        this.tableSet.add(table);
        return this;
    }

    public TableRowClassSourceCodeGenerator excludeTables(Collection tables) {
        this.excludedTableSet.addAll(tables);
        return this;
    }

    public TableRowClassSourceCodeGenerator setProvideConstSchema(boolean provideConstSchema) {
        this.provideConstSchema = provideConstSchema;
        return this;
    }

    public TableRowClassSourceCodeGenerator setProvideConstSchemaAndTable(boolean provideConstSchemaAndTable) {
        this.provideConstSchemaAndTable = provideConstSchemaAndTable;
        return this;
    }

    public TableRowClassSourceCodeGenerator setProvideConstTable(boolean provideConstTable) {
        this.provideConstTable = provideConstTable;
        return this;
    }

    /**
     * @param strictEnumPackage empty or a package path. No dot in tail.
     */
    public TableRowClassSourceCodeGenerator setStrictEnumPackage(@Nonnull String strictEnumPackage) {
        this.strictEnumPackage = strictEnumPackage;
        return this;
    }

    /**
     * @param envelopePackage empty or a package path. No dot in tail.
     * @since 3.1.0
     */
    public TableRowClassSourceCodeGenerator setEnvelopePackage(@Nonnull String envelopePackage) {
        this.envelopePackage = envelopePackage;
        return this;
    }

    public Future generate(String packageName, String packagePath) {
        return this.confirmTablesToGenerate()
                .compose(tables -> generateForTables(packageName, packagePath, tables));
    }

    private Future> confirmTablesToGenerate() {
        Set tables = new HashSet<>();
        if (this.tableSet.isEmpty()) {
            if (schema == null || schema.isEmpty() || schema.isBlank()) {
                return this.sqlConnection.query("show tables")
                        .execute()
                        .compose(rows -> {
                            rows.forEach(row -> {
                                String tableName = row.getString(0);
                                tables.add(tableName);
                            });
                            if (!this.excludedTableSet.isEmpty()) {
                                tables.removeAll(this.excludedTableSet);
                            }
                            return Future.succeededFuture(tables);
                        });
            } else {
                return this.sqlConnection.query("show tables in `" + this.schema + "`")
                        .execute()
                        .compose(rows -> {
                            rows.forEach(row -> {
                                String tableName = row.getString(0);
                                tables.add(tableName);
                            });
                            if (!this.excludedTableSet.isEmpty()) {
                                tables.removeAll(this.excludedTableSet);
                            }
                            return Future.succeededFuture(tables);
                        });
            }
        } else {
            tables.addAll(this.tableSet);
            if (!this.excludedTableSet.isEmpty()) {
                tables.removeAll(this.excludedTableSet);
            }
            return Future.succeededFuture(tables);
        }
    }

    private Future generateForTables(String packageName, String packagePath, Collection tables) {
        Map writeMap = new HashMap<>();
        return KeelAsyncKit.iterativelyCall(
                        tables,
                        table -> {
                            String className = KeelHelpers.stringHelper().fromUnderScoreCaseToCamelCase(table) + "TableRow";
                            String classFile = packagePath + "/" + className + ".java";
                            return this.generateClassCodeForOneTable(schema, table, packageName, className)
                                    .compose(code -> {
                                        writeMap.put(classFile, code);
                                        return Future.succeededFuture();
                                    });
                        })
                .compose(v -> {
                    return KeelAsyncKit.iterativelyCall(writeMap.entrySet(), entry -> {
                        var classFile = entry.getKey();
                        var code = entry.getValue();
                        return Keel.getVertx().fileSystem().writeFile(classFile, Buffer.buffer(code));
                    });
                });
    }

    private Future generateClassCodeForOneTable(String schema, String table, String packageName, String className) {
        return Future.all(
                        this.getCommentOfTable(table, schema),// comment of table
                        this.getFieldsOfTable(table, schema),// fields
                        this.getCreationOfTable(table, schema)// creation ddl
                )
                .compose(compositeFuture -> {
                    String table_comment = compositeFuture.resultAt(0);
                    List fields = compositeFuture.resultAt(1);
                    String creation = compositeFuture.resultAt(2);

                    String code = new TableRowClassBuilder(table, schema, packageName)
                            .setTableComment(table_comment)
                            .setDdl(creation)
                            .setProvideConstTable(provideConstTable)
                            .setProvideConstSchema(provideConstSchema)
                            .setProvideConstSchemaAndTable(provideConstSchemaAndTable)
                            .addFields(fields)
                            .build();
                    return Future.succeededFuture(code);
                });
    }

    /**
     * Fetch comment of a table (in schema).
     */
    private Future getCommentOfTable(@Nonnull String table, @Nullable String schema) {
        String sql_for_table_comment = "SELECT TABLE_COMMENT " +
                "FROM INFORMATION_SCHEMA.TABLES " +
                "WHERE TABLE_NAME = '" + table + "' " +
                (schema == null ? "" : ("AND TABLE_SCHEMA = '" + schema + "' "));
        return sqlConnection.query(sql_for_table_comment).execute()
                .compose(rows -> {
                    AtomicReference comment = new AtomicReference<>();
                    rows.forEach(row -> {
                        comment.set(row.getString("TABLE_COMMENT"));
                    });
                    return Future.succeededFuture(comment.get());
                });
    }

    private Future> getFieldsOfTable(@Nonnull String table, @Nullable String schema) {
        String sql_for_columns = "show full columns in ";
        if (schema != null && !schema.isEmpty() && !schema.isBlank()) {
            sql_for_columns += "`" + schema + "`.";
        }
        sql_for_columns += "`" + table + "`;";

        return sqlConnection.query(sql_for_columns)
                .execute()
                .compose(rows -> {
                    List fields = new ArrayList<>();
                    rows.forEach(row -> {
                        String field = row.getString("Field");
                        String type = row.getString("Type");
                        String comment = row.getString("Comment");
                        if (comment == null || comment.isEmpty() || comment.isBlank()) {
                            comment = null;
                        }

                        // since 3.1.10
                        String nullability = row.getString("Null");
                        boolean isNullable = "YES".equalsIgnoreCase(nullability);

                        fields.add(new TableRowClassField(field, type, isNullable, comment, strictEnumPackage, envelopePackage));
                    });
                    return Future.succeededFuture(fields);
                });
    }

    private Future getCreationOfTable(@Nonnull String table, @Nullable String schema) {
        String sql_sct = "show create table ";
        if (schema != null) {
            sql_sct += "`" + schema + "`.";
        }
        sql_sct += "`" + table + "`;";
        return sqlConnection.query(sql_sct)
                .execute()
                .compose(rows -> {
                    AtomicReference creation = new AtomicReference<>();
                    rows.forEach(row -> {
                        creation.set(row.getString(1));
                    });
                    return Future.succeededFuture(creation.get());
                });
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy