<commit_before>package org.dbflute.erflute.db.impl.mysql;

import java.util.List;

import org.dbflute.erflute.core.DisplayMessages;
import org.dbflute.erflute.core.util.Check;
import org.dbflute.erflute.core.util.Format;
import org.dbflute.erflute.db.DBManager;
import org.dbflute.erflute.db.impl.mysql.tablespace.MySQLTablespaceProperties;
import org.dbflute.erflute.db.sqltype.SqlType;
import org.dbflute.erflute.editor.model.ERDiagram;
import org.dbflute.erflute.editor.model.dbexport.ddl.DDLCreator;
import org.dbflute.erflute.editor.model.diagram_contents.element.node.table.ERTable;
import org.dbflute.erflute.editor.model.diagram_contents.element.node.table.column.NormalColumn;
import org.dbflute.erflute.editor.model.diagram_contents.element.node.table.index.ERIndex;
import org.dbflute.erflute.editor.model.diagram_contents.not_element.tablespace.Tablespace;

/**
 * @author modified by jflute (originated in ermaster)
 */
public class MySQLDDLCreator extends DDLCreator {

    // ===================================================================================
    //                                                                         Constructor
    //                                                                         ===========
    public MySQLDDLCreator(ERDiagram diagram, boolean semicolon) {
        super(diagram, semicolon);
    }

    // ===================================================================================
    //                                                                            Drop DDL
    //                                                                            ========
    @Override
    public String prepareDropDDL(ERDiagram diagram) {
        final String dropDDL = super.prepareDropDDL(diagram);
        if (dropDDL.isEmpty()) {
            return dropDDL;
        }
        final StringBuilder ddl = new StringBuilder();
        ddl.append("SET SESSION FOREIGN_KEY_CHECKS=0");
        if (this.semicolon) {
            ddl.append(";");
        }
        ddl.append("\r\n");
        ddl.append(dropDDL);
        return ddl.toString();
    }

    @Override
    public String doBuildDropIndex(ERIndex index, ERTable table) {
        final StringBuilder ddl = new StringBuilder();
        ddl.append("DROP INDEX ");
        ddl.append(this.getIfExistsOption());
        ddl.append(filter(index.getName()));
        ddl.append(" ON ");
        ddl.append(filter(table.getNameWithSchema(this.getDiagram().getDatabase())));
        if (this.semicolon) {
            ddl.append(";");
        }
        return ddl.toString();
    }

    // ===================================================================================
    //                                                                   Create Tablespace
    //                                                                   =================
    @Override
    protected String doBuildCreateTablespace(Tablespace tablespace) {
        final MySQLTablespaceProperties tablespaceProperties =
                (MySQLTablespaceProperties) tablespace.getProperties(this.environment, this.getDiagram());
        final StringBuilder ddl = new StringBuilder();
        ddl.append("CREATE TABLESPACE ");
        ddl.append(filter(tablespace.getName()));
        ddl.append("\r\n");
        ddl.append(" ADD DATAFILE '");
        ddl.append(tablespaceProperties.getDataFile());
        ddl.append("'\r\n");
        ddl.append(" USE LOGFILE GROUP ");
        ddl.append(tablespaceProperties.getLogFileGroup());
        ddl.append("\r\n");
        if (!Check.isEmpty(tablespaceProperties.getExtentSize())) {
            ddl.append(" EXTENT_SIZE ");
            ddl.append(tablespaceProperties.getExtentSize());
            ddl.append("\r\n");
        }
        ddl.append(" INITIAL_SIZE ");
        ddl.append(tablespaceProperties.getInitialSize());
        ddl.append("\r\n");
        ddl.append(" ENGINE ");
        ddl.append(tablespaceProperties.getEngine());
        ddl.append("\r\n");
        if (this.semicolon) {
            ddl.append(";");
        }
        return ddl.toString();
    }

    // ===================================================================================
    //                                                                        Create Table
    //                                                                        ============
    @Override
    protected String buildColumnPart(NormalColumn normalColumn) {
        final StringBuilder ddl = new StringBuilder();
        final String description = normalColumn.getDescription();
        if (this.semicolon && !Check.isEmpty(description) && this.ddlTarget.inlineColumnComment) {
            ddl.append("\t-- ");
            ddl.append(description.replaceAll("\n", "\n\t-- "));
            ddl.append("\r\n");
        }
        ddl.append("\t");
        ddl.append(filter(normalColumn.getPhysicalName()));
        ddl.append(" ");
        ddl.append(filter(Format.formatType(normalColumn.getType(), normalColumn.getTypeData(), this.getDiagram().getDatabase())));
        if (!Check.isEmpty(normalColumn.getCharacterSet())) {
            ddl.append(" CHARACTER SET ");
            ddl.append(normalColumn.getCharacterSet());
            if (!Check.isEmpty(normalColumn.getCollation())) {
                ddl.append(" COLLATE ");
                ddl.append(normalColumn.getCollation());
            }
        }
        if (!Check.isEmpty(normalColumn.getDefaultValue())) {
            String defaultValue = normalColumn.getDefaultValue();
            if (DisplayMessages.getMessage("label.current.date.time").equals(defaultValue)) {
                defaultValue = this.getDBManager().getCurrentTimeValue()[0];
            }
            ddl.append(" DEFAULT ");
            if (this.doesNeedQuoteDefaultValue(normalColumn)) {
                ddl.append("'");
                ddl.append(Format.escapeSQL(defaultValue));
                ddl.append("'");
            } else {
                ddl.append(defaultValue);
            }
        }
        if (normalColumn.isNotNull()) {
            ddl.append(" NOT NULL");
        }
        if (normalColumn.isUniqueKey()) {
            if (!Check.isEmpty(normalColumn.getUniqueKeyName())) {
                ddl.append(" CONSTRAINT ");
                ddl.append(normalColumn.getUniqueKeyName());
            }
            ddl.append(" UNIQUE");
        }
        final String constraint = Format.null2blank(normalColumn.getConstraint());
        if (!"".equals(constraint)) {
            ddl.append(" ");
            ddl.append(constraint);
        }
        if (normalColumn.isAutoIncrement()) {
            ddl.append(" AUTO_INCREMENT");
        }
        if (this.ddlTarget.createComment) {
            final String comment = this.filterComment(normalColumn.getLogicalName(), normalColumn.getDescription(), true);
            if (!Check.isEmpty(comment)) {
                ddl.append(" COMMENT '");
                ddl.append(comment.replaceAll("'", "''"));
                ddl.append("'");
            }
        }
        return ddl.toString();
    }

    @Override
    protected boolean doesNeedQuoteDefaultValue(NormalColumn normalColumn) {
        if (!super.doesNeedQuoteDefaultValue(normalColumn)) {
            return false;
        }
        if ("CURRENT_TIMESTAMP".equalsIgnoreCase(normalColumn.getDefaultValue().trim())) {
            return false;
        }
        return true;<commit_msg>fix binary constraint, from ERMaster-b-1.5.0.3<commit_after>package org.dbflute.erflute.db.impl.mysql;

import java.util.List;

import org.dbflute.erflute.core.DisplayMessages;
import org.dbflute.erflute.core.util.Check;
import org.dbflute.erflute.core.util.Format;
import org.dbflute.erflute.db.DBManager;
import org.dbflute.erflute.db.impl.mysql.tablespace.MySQLTablespaceProperties;
import org.dbflute.erflute.db.sqltype.SqlType;
import org.dbflute.erflute.editor.model.ERDiagram;
import org.dbflute.erflute.editor.model.dbexport.ddl.DDLCreator;
import org.dbflute.erflute.editor.model.diagram_contents.element.node.table.ERTable;
import org.dbflute.erflute.editor.model.diagram_contents.element.node.table.column.NormalColumn;
import org.dbflute.erflute.editor.model.diagram_contents.element.node.table.index.ERIndex;
import org.dbflute.erflute.editor.model.diagram_contents.not_element.tablespace.Tablespace;

/**
 * @author modified by jflute (originated in ermaster)
 */
public class MySQLDDLCreator extends DDLCreator {

    // ===================================================================================
    //                                                                         Constructor
    //                                                                         ===========
    public MySQLDDLCreator(ERDiagram diagram, boolean semicolon) {
        super(diagram, semicolon);
    }

    // ===================================================================================
    //                                                                            Drop DDL
    //                                                                            ========
    @Override
    public String prepareDropDDL(ERDiagram diagram) {
        final String dropDDL = super.prepareDropDDL(diagram);
        if (dropDDL.isEmpty()) {
            return dropDDL;
        }
        final StringBuilder ddl = new StringBuilder();
        ddl.append("SET SESSION FOREIGN_KEY_CHECKS=0");
        if (this.semicolon) {
            ddl.append(";");
        }
        ddl.append("\r\n");
        ddl.append(dropDDL);
        return ddl.toString();
    }

    @Override
    public String doBuildDropIndex(ERIndex index, ERTable table) {
        final StringBuilder ddl = new StringBuilder();
        ddl.append("DROP INDEX ");
        ddl.append(this.getIfExistsOption());
        ddl.append(filter(index.getName()));
        ddl.append(" ON ");
        ddl.append(filter(table.getNameWithSchema(this.getDiagram().getDatabase())));
        if (this.semicolon) {
            ddl.append(";");
        }
        return ddl.toString();
    }

    // ===================================================================================
    //                                                                   Create Tablespace
    //                                                                   =================
    @Override
    protected String doBuildCreateTablespace(Tablespace tablespace) {
        final MySQLTablespaceProperties tablespaceProperties =
                (MySQLTablespaceProperties) tablespace.getProperties(this.environment, this.getDiagram());
        final StringBuilder ddl = new StringBuilder();
        ddl.append("CREATE TABLESPACE ");
        ddl.append(filter(tablespace.getName()));
        ddl.append("\r\n");
        ddl.append(" ADD DATAFILE '");
        ddl.append(tablespaceProperties.getDataFile());
        ddl.append("'\r\n");
        ddl.append(" USE LOGFILE GROUP ");
        ddl.append(tablespaceProperties.getLogFileGroup());
        ddl.append("\r\n");
        if (!Check.isEmpty(tablespaceProperties.getExtentSize())) {
            ddl.append(" EXTENT_SIZE ");
            ddl.append(tablespaceProperties.getExtentSize());
            ddl.append("\r\n");
        }
        ddl.append(" INITIAL_SIZE ");
        ddl.append(tablespaceProperties.getInitialSize());
        ddl.append("\r\n");
        ddl.append(" ENGINE ");
        ddl.append(tablespaceProperties.getEngine());
        ddl.append("\r\n");
        if (this.semicolon) {
            ddl.append(";");
        }
        return ddl.toString();
    }

    // ===================================================================================
    //                                                                        Create Table
    //                                                                        ============
    @Override
    protected String buildColumnPart(NormalColumn normalColumn) {
        final StringBuilder ddl = new StringBuilder();
        final String description = normalColumn.getDescription();
        if (this.semicolon && !Check.isEmpty(description) && this.ddlTarget.inlineColumnComment) {
            ddl.append("\t-- ");
            ddl.append(description.replaceAll("\n", "\n\t-- "));
            ddl.append("\r\n");
        }
        ddl.append("\t");
        ddl.append(filter(normalColumn.getPhysicalName()));
        ddl.append(" ");
        ddl.append(filter(Format.formatType(normalColumn.getType(), normalColumn.getTypeData(), this.getDiagram().getDatabase())));
        if (!Check.isEmpty(normalColumn.getCharacterSet())) {
            ddl.append(" CHARACTER SET ");
            ddl.append(normalColumn.getCharacterSet());
            if (!Check.isEmpty(normalColumn.getCollation())) {
                ddl.append(" COLLATE ");
                ddl.append(normalColumn.getCollation());
            }
        }
        if (!Check.isEmpty(normalColumn.getDefaultValue())) {
            String defaultValue = normalColumn.getDefaultValue();
            if (DisplayMessages.getMessage("label.current.date.time").equals(defaultValue)) {
                defaultValue = this.getDBManager().getCurrentTimeValue()[0];
            }
            ddl.append(" DEFAULT ");
            if (this.doesNeedQuoteDefaultValue(normalColumn)) {
                ddl.append("'");
                ddl.append(Format.escapeSQL(defaultValue));
                ddl.append("'");
            } else {
                ddl.append(defaultValue);
            }
        }
        // from https://github.com/naoki-iwami/ermaster-b/commit/048b7fa7ffa3d6fd34c2918b44e73c7615aa2bfe
        String constraint = Format.null2blank(normalColumn.getConstraint());
        if ("BINARY".equalsIgnoreCase(constraint)) {
            ddl.append(" ");
            ddl.append(constraint);
            constraint = "";
        }
        if (normalColumn.isNotNull()) {
            ddl.append(" NOT NULL");
        }
        if (!"".equals(constraint)) {
            ddl.append(" ");
            ddl.append(constraint);
        }
        if (normalColumn.isUniqueKey()) {
            if (!Check.isEmpty(normalColumn.getUniqueKeyName())) {
                ddl.append(" CONSTRAINT ");
                ddl.append(normalColumn.getUniqueKeyName());
            }
            ddl.append(" UNIQUE");
        }
        if (normalColumn.isAutoIncrement()) {
            ddl.append(" AUTO_INCREMENT");
        }
        if (this.ddlTarget.createComment) {
            final String comment = this.filterComment(normalColumn.getLogicalName(), normalColumn.getDescription(), true);
            if (!Check.isEmpty(comment)) {
                ddl.append(" COMMENT '");
                ddl.append(comment.replaceAll("'", "''"));
                ddl.append("'");
            }
        }
        return ddl.toString();
    }

    @Override
    protected boolean doesNeedQuoteDefaultValue(NormalColumn normalColumn) {
        if (!super.doesNeedQuoteDefaultValue(normalColumn)) {
            return false;
        }
        if ("CURRENT_TIMESTAMP".equalsIgnoreCase(normalColumn.getDefaultValue().trim())) {
            return false;
        }
        return true;
{'fraction_non_alphanumeric': 0.16697380544951954, 'fraction_numerical': 0.0021060945109911806, 'mean_word_length': 1.9735812133072408, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 48, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5710148', 'n_tokens_mistral': 3962, 'n_tokens_neox': 3862, 'n_words': 549}