001/*
002 *  Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.query;
017
018import com.mybatisflex.core.FlexConsts;
019import com.mybatisflex.core.constant.SqlConsts;
020import com.mybatisflex.core.dialect.IDialect;
021import com.mybatisflex.core.util.CollectionUtil;
022import com.mybatisflex.core.util.StringUtil;
023
024import java.util.ArrayList;
025import java.util.Arrays;
026import java.util.List;
027
028public class DistinctQueryColumn extends QueryColumn implements HasParamsColumn {
029
030    private List<QueryColumn> queryColumns;
031
032    public DistinctQueryColumn(QueryColumn... queryColumns) {
033        this.queryColumns = CollectionUtil.newArrayList(queryColumns);
034    }
035
036    public List<QueryColumn> getQueryColumns() {
037        return queryColumns;
038    }
039
040    public void setQueryColumns(List<QueryColumn> queryColumns) {
041        this.queryColumns = queryColumns;
042    }
043
044    @Override
045    String toConditionSql(List<QueryTable> queryTables, IDialect dialect) {
046        if (CollectionUtil.isEmpty(queryTables)) {
047            return SqlConsts.EMPTY;
048        }
049
050        return SqlConsts.DISTINCT + StringUtil.join(
051            SqlConsts.DELIMITER,
052            queryColumns,
053            queryColumn -> queryColumn.toSelectSql(queryTables, dialect)
054        );
055    }
056
057    @Override
058    public String toSelectSql(List<QueryTable> queryTables, IDialect dialect) {
059        if (CollectionUtil.isEmpty(queryTables)) {
060            return SqlConsts.EMPTY;
061        }
062
063        String sql = SqlConsts.DISTINCT + StringUtil.join(
064            SqlConsts.DELIMITER,
065            queryColumns,
066            queryColumn -> queryColumn.toSelectSql(queryTables, dialect)
067        );
068
069        return sql + WrapperUtil.buildColumnAlias(alias, dialect);
070    }
071
072    @Override
073    public DistinctQueryColumn clone() {
074        DistinctQueryColumn clone = (DistinctQueryColumn) super.clone();
075        // deep clone ...
076        clone.queryColumns = CollectionUtil.cloneArrayList(this.queryColumns);
077
078        return clone;
079    }
080
081    @Override
082    public Object[] getParamValues() {
083        if (CollectionUtil.isEmpty(queryColumns)) {
084            return FlexConsts.EMPTY_ARRAY;
085        }
086
087        List<Object> params = new ArrayList<>();
088
089        for (QueryColumn queryColumn : queryColumns) {
090            if (queryColumn instanceof HasParamsColumn) {
091                Object[] paramValues = ((HasParamsColumn) queryColumn).getParamValues();
092
093                params.addAll(Arrays.asList(paramValues));
094            }
095        }
096
097        return params.toArray();
098    }
099}