001/*
002 *  Copyright (c) 2022-2023, 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.constant.SqlConsts;
019import com.mybatisflex.core.dialect.IDialect;
020import com.mybatisflex.core.exception.FlexExceptions;
021import com.mybatisflex.core.util.ObjectUtil;
022
023import java.util.ArrayList;
024import java.util.List;
025import java.util.function.Supplier;
026
027/**
028 * @author michael yang (fuhai999@gmail.com)
029 * @Date: 2020/1/14
030 */
031public class Join implements CloneSupport<Join> {
032
033    private static final long serialVersionUID = 1L;
034
035
036    protected final String type;
037    protected QueryTable queryTable;
038    protected QueryCondition on;
039    protected boolean effective;
040
041    public Join(String type, QueryTable table, boolean when) {
042        this.type = type;
043        this.queryTable = table;
044        this.effective = when;
045    }
046
047    public Join(String type, QueryWrapper queryWrapper, boolean when) {
048        this.type = type;
049        this.queryTable = new SelectQueryTable(queryWrapper);
050        this.effective = when;
051    }
052
053
054    QueryTable getQueryTable() {
055        return queryTable;
056    }
057
058
059    public void on(QueryCondition condition) {
060        if (condition.column != null){
061            QueryTable table = condition.column.getTable();
062            if (queryTable.isSameTable(table)){
063                QueryColumn newColumn = condition.column.clone();
064                newColumn.table.alias = queryTable.alias;
065                condition.column = newColumn;
066            }
067        }
068        this.on = condition;
069    }
070
071    QueryCondition getOnCondition() {
072        return on;
073    }
074
075    public boolean checkEffective() {
076        return effective;
077    }
078
079    public void when(boolean when) {
080        this.effective = when;
081    }
082
083    public void when(Supplier<Boolean> fn) {
084        this.effective = fn.get();
085    }
086
087    public String toSql(List<QueryTable> queryTables, IDialect dialect) {
088        //left join, right join,  inner join ...
089        StringBuilder sql = new StringBuilder(type);
090        sql.append(queryTable.toSql(dialect));
091
092        //left join xxx as xxx2 on xxx2.id = xxx3.other
093        List<QueryTable> newQueryTables = new ArrayList<>(queryTables);
094        newQueryTables.add(queryTable);
095        sql.append(SqlConsts.ON).append(on.toSql(newQueryTables, dialect));
096        return sql.toString();
097    }
098
099    @Override
100    public Join clone() {
101        try {
102            Join clone = (Join) super.clone();
103            // deep clone ...
104            clone.queryTable = ObjectUtil.clone(this.queryTable);
105            clone.on = ObjectUtil.clone(this.on);
106            return clone;
107        } catch (CloneNotSupportedException e) {
108            throw FlexExceptions.wrap(e);
109        }
110    }
111
112}