001/*
002 * (C) Copyright 2006-2018 Nuxeo (http://nuxeo.com/) and others.
003 *
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 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
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 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.storage.sql.jdbc.db;
020
021import java.io.Serializable;
022import java.util.Collections;
023import java.util.LinkedList;
024import java.util.List;
025import java.util.Set;
026
027import org.apache.commons.lang3.StringUtils;
028
029/**
030 * An {@code UPDATE} statement.
031 */
032public class Update implements Serializable {
033
034    private static final long serialVersionUID = 1L;
035
036    protected final Table table;
037
038    protected String newValues;
039
040    protected String[] from;
041
042    protected String where;
043
044    public Update(Table table) {
045        this.table = table;
046    }
047
048    public Table getTable() {
049        return table;
050    }
051
052    public void setNewValues(String newValues) {
053        this.newValues = newValues;
054    }
055
056    /** Alternative to {@link #setNewValues} */
057    public void setUpdatedColumns(List<Column> columns) {
058        setUpdatedColumns(columns, Collections.emptySet());
059    }
060
061    /**
062     * Alternative to {@link #setNewValues}
063     *
064     * @param columns the columns
065     * @param deltas which of the columns are delta updates
066     */
067    public void setUpdatedColumns(List<Column> columns, Set<String> deltas) {
068        List<String> updatedColumns = new LinkedList<>();
069        for (Column column : columns) {
070            if (column.isIdentity()) {
071                // identity column is never inserted
072                continue;
073            }
074            String col = column.getQuotedName();
075            String fvs = column.getFreeVariableSetter();
076            String update;
077            if (deltas.contains(column.getKey())) {
078                update = col + " = " + col + " + " + fvs;
079            } else {
080                update = col + " = " + fvs;
081            }
082            updatedColumns.add(update);
083        }
084        newValues = StringUtils.join(updatedColumns, ", ");
085    }
086
087    /**
088     * Sets additional table names with which to join for this update.
089     */
090    public void setFrom(String... from) {
091        this.from = from;
092    }
093
094    public void setWhere(String where) {
095        if (where == null || where.length() == 0) {
096            throw new IllegalArgumentException("unexpected empty WHERE");
097        }
098        this.where = where;
099    }
100
101    public String getStatement() {
102        StringBuilder sb = new StringBuilder(128);
103        sb.append("UPDATE ");
104        sb.append(table.getQuotedName());
105        sb.append(" SET ");
106        sb.append(newValues);
107        if (from != null) {
108            sb.append(" FROM ");
109            if (table.getDialect().doesUpdateFromRepeatSelf()) {
110                sb.append(table.getQuotedName());
111                sb.append(", ");
112            }
113            sb.append(StringUtils.join(from, ", "));
114        }
115        if (where != null) {
116            sb.append(" WHERE ");
117            sb.append(where);
118        } else {
119            throw new IllegalArgumentException("unexpected empty WHERE");
120        }
121        return sb.toString();
122    }
123}