001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jpa.search.builder.sql;
021
022import com.healthmarketscience.common.util.AppendableExt;
023import com.healthmarketscience.sqlbuilder.SqlContext;
024import com.healthmarketscience.sqlbuilder.SqlObject;
025import com.healthmarketscience.sqlbuilder.ValidationContext;
026import com.healthmarketscience.sqlbuilder.dbspec.Column;
027import com.healthmarketscience.sqlbuilder.dbspec.Table;
028import com.healthmarketscience.sqlbuilder.dbspec.basic.DbColumn;
029
030import java.io.IOException;
031import java.util.Iterator;
032import java.util.List;
033
034import static org.apache.commons.lang3.StringUtils.isNotBlank;
035
036public class ColumnTupleObject extends SqlObject {
037
038        private final List<Column> myColumns;
039
040        public ColumnTupleObject(Column... theColumns) {
041                myColumns = List.of(theColumns);
042        }
043
044        @Override
045        protected void collectSchemaObjects(ValidationContext vContext) {
046                myColumns.forEach(vContext::addColumn);
047        }
048
049        @Override
050        public void appendTo(AppendableExt app) throws IOException {
051                app.append('(');
052
053                for (Iterator<Column> iter = myColumns.iterator(); iter.hasNext(); ) {
054                        Column column = iter.next();
055                        appendTableAliasPrefix(app, column.getTable());
056                        app.append(column.getColumnNameSQL());
057
058                        if (iter.hasNext()) {
059                                app.append(',');
060                        }
061                }
062
063                app.append(')');
064        }
065
066        /**
067         * Outputs the table alias prefix <code>"[&lt;tableAlias&gt;.]"</code> for a
068         * column reference if the current SqlContext specifies table aliases should
069         * be used (and the table has an alias), otherwise does nothing.
070         */
071        static void appendTableAliasPrefix(AppendableExt app, Table table) throws IOException {
072                if (SqlContext.getContext(app).getUseTableAliases()) {
073                        String alias = table.getAlias();
074                        if (isNotBlank(alias)) {
075                                app.append(alias).append(".");
076                        }
077                }
078        }
079
080        public static Object from(DbColumn[] theJoinColumns) {
081                if (theJoinColumns.length == 1) {
082                        return theJoinColumns[0];
083                } else {
084                        return new ColumnTupleObject(theJoinColumns);
085                }
086        }
087}