<commit_before>/*
 * Stratio Meta
 *
 * Copyright (c) 2014, Stratio, All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3.0 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.
 */

package com.stratio.meta.core.statements;

import com.stratio.meta.core.metadata.MetadataManager;
import com.stratio.meta.core.structures.Assignment;
import com.stratio.meta.core.structures.Option;
import com.stratio.meta.core.structures.Relation;
import com.stratio.meta.core.structures.Term;
import com.stratio.meta.core.utils.ParserUtils;
import com.stratio.meta.core.utils.Tree;

import java.util.List;
import java.util.Map;

/**
 * Class that models an {@code UPDATE} statement from the META language.
 */
public class UpdateTableStatement extends MetaStatement {

    /**
     * The name of the table.
     */
    private String tableName;

    /**
     * Whether options are included.
     */
    private boolean optsInc;

    /**
     * The list of options.
     */
    private List<Option> options;

    /**
     * The list of assignments.
     */
    private List<Assignment> assignments;

    /**
     * The list of relations.
     */
    private List<Relation> whereClauses;

    /**
     * Whether conditions are included.
     */
    private boolean condsInc;

    /**
     * Map of conditions.
     */
    private Map<String, Term> conditions;

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param optsInc Whether options are included.
     * @param options The list of options.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     * @param condsInc Whether conditions are included.
     * @param conditions The map of conditions.
     */
    public UpdateTableStatement(String tableName,
                                boolean optsInc, 
                                List<Option> options, 
                                List<Assignment> assignments, 
                                List<Relation> whereClauses,
                                boolean condsInc, 
                                Map<String, Term> conditions) {
        this.command = false;
        if(tableName.contains(".")){
            String[] ksAndTableName = tableName.split("\\.");
            keyspace = ksAndTableName[0];
            this.tableName = ksAndTableName[1];
            keyspaceInc = true;
        }else{
            this.tableName = tableName;
        }

        this.optsInc = optsInc;
        this.options = options;
        this.assignments = assignments;
        this.whereClauses = whereClauses;
        this.condsInc = condsInc;
        this.conditions = conditions;
    }

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param options The list of options.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     * @param conditions The map of conditions.
     */
    public UpdateTableStatement(String tableName,
                                List<Option> options, 
                                List<Assignment> assignments, 
                                List<Relation> whereClauses,
                                Map<String, Term> conditions) {
        this(tableName, true, options, assignments, whereClauses, true, conditions);
    }

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     * @param conditions The map of conditions.
     */
    public UpdateTableStatement(String tableName,
                                List<Assignment> assignments, 
                                List<Relation> whereClauses,
                                Map<String, Term> conditions) {
        this(tableName, false, null, assignments, whereClauses, true, conditions);
    }

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param options The list of options.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     */
    public UpdateTableStatement(String tableName,
                                List<Option> options, 
                                List<Assignment> assignments, 
                                List<Relation> whereClauses) {
        this(tableName, true, options, assignments, whereClauses, false, null);
    }

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     */
    public UpdateTableStatement(String tableName,
                                List<Assignment> assignments, 
                                List<Relation> whereClauses) {
        this(tableName, false, null, assignments, whereClauses, false, null);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("UPDATE ");
        if(keyspaceInc){
            sb.append(keyspace).append(".");
        }
        sb.append(tableName);
        if(optsInc){
            sb.append(" ").append("USING ");
            sb.append(ParserUtils.stringList(options, " AND "));
        }
        sb.append(" ").append("SET ");
        sb.append(ParserUtils.stringList(assignments, ", "));
        sb.append(" ").append("WHERE ");
        sb.append(ParserUtils.stringList(whereClauses, " AND "));
        if(condsInc){
            sb.append(" ").append("IF ");
            sb.append(ParserUtils.stringMap(conditions, " = ", " AND "));
        }
        return sb.toString();
    }

    @Override
    public String translateToCQL() {
        return this.toString();
    }

    @Override
    public Tree getPlan(MetadataManager metadataManager, String targetKeyspace) {
        return new Tree();
    }
    
}<commit_msg>Validator v1 for UpdateTableStatement<commit_after>/*
 * Stratio Meta
 *
 * Copyright (c) 2014, Stratio, All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3.0 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.
 */

package com.stratio.meta.core.statements;

import com.datastax.driver.core.ColumnMetadata;
import com.datastax.driver.core.TableMetadata;
import com.stratio.meta.common.result.QueryResult;
import com.stratio.meta.common.result.Result;
import com.stratio.meta.core.metadata.MetadataManager;
import com.stratio.meta.core.structures.Assignment;
import com.stratio.meta.core.structures.Option;
import com.stratio.meta.core.structures.Relation;
import com.stratio.meta.core.structures.Term;
import com.stratio.meta.core.utils.ParserUtils;
import com.stratio.meta.core.utils.Tree;

import java.util.List;
import java.util.Map;

/**
 * Class that models an {@code UPDATE} statement from the META language.
 */
public class UpdateTableStatement extends MetaStatement {

    /**
     * The name of the table.
     */
    private String tableName;

    /**
     * Whether options are included.
     */
    private boolean optsInc;

    /**
     * The list of options.
     */
    private List<Option> options;

    /**
     * The list of assignments.
     */
    private List<Assignment> assignments;

    /**
     * The list of relations.
     */
    private List<Relation> whereClauses;

    /**
     * Whether conditions are included.
     */
    private boolean condsInc;

    /**
     * Map of conditions.
     */
    private Map<String, Term> conditions;

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param optsInc Whether options are included.
     * @param options The list of options.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     * @param condsInc Whether conditions are included.
     * @param conditions The map of conditions.
     */
    public UpdateTableStatement(String tableName,
                                boolean optsInc, 
                                List<Option> options, 
                                List<Assignment> assignments, 
                                List<Relation> whereClauses,
                                boolean condsInc, 
                                Map<String, Term> conditions) {
        this.command = false;
        if(tableName.contains(".")){
            String[] ksAndTableName = tableName.split("\\.");
            keyspace = ksAndTableName[0];
            this.tableName = ksAndTableName[1];
            keyspaceInc = true;
        }else{
            this.tableName = tableName;
        }

        this.optsInc = optsInc;

        //this.options = options;
        for(Option opt: options){
            opt.setNameProperty(opt.getNameProperty().toLowerCase());
            this.options.add(opt);
        }

        this.assignments = assignments;
        this.whereClauses = whereClauses;
        this.condsInc = condsInc;
        this.conditions = conditions;
    }

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param options The list of options.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     * @param conditions The map of conditions.
     */
    public UpdateTableStatement(String tableName,
                                List<Option> options, 
                                List<Assignment> assignments, 
                                List<Relation> whereClauses,
                                Map<String, Term> conditions) {
        this(tableName, true, options, assignments, whereClauses, true, conditions);
    }

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     * @param conditions The map of conditions.
     */
    public UpdateTableStatement(String tableName,
                                List<Assignment> assignments, 
                                List<Relation> whereClauses,
                                Map<String, Term> conditions) {
        this(tableName, false, null, assignments, whereClauses, true, conditions);
    }

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param options The list of options.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     */
    public UpdateTableStatement(String tableName,
                                List<Option> options, 
                                List<Assignment> assignments, 
                                List<Relation> whereClauses) {
        this(tableName, true, options, assignments, whereClauses, false, null);
    }

    /**
     * Class constructor.
     * @param tableName The name of the table.
     * @param assignments The list of assignments.
     * @param whereClauses The list of relations.
     */
    public UpdateTableStatement(String tableName,
                                List<Assignment> assignments, 
                                List<Relation> whereClauses) {
        this(tableName, false, null, assignments, whereClauses, false, null);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("UPDATE ");
        if(keyspaceInc){
            sb.append(keyspace).append(".");
        }
        sb.append(tableName);
        if(optsInc){
            sb.append(" ").append("USING ");
            sb.append(ParserUtils.stringList(options, " AND "));
        }
        sb.append(" ").append("SET ");
        sb.append(ParserUtils.stringList(assignments, ", "));
        sb.append(" ").append("WHERE ");
        sb.append(ParserUtils.stringList(whereClauses, " AND "));
        if(condsInc){
            sb.append(" ").append("IF ");
            sb.append(ParserUtils.stringMap(conditions, " = ", " AND "));
        }
        return sb.toString();
    }

    @Override
    public String translateToCQL() {
        return this.toString();
    }

    /**
     * Validate the semantics of the current statement. This method checks the
     * existing metadata to determine that all referenced entities exists in the
     * {@code targetKeyspace} and the types are compatible with the assignations
     * or comparisons.
     *
     * @param metadata The {@link com.stratio.meta.core.metadata.MetadataManager} that provides
     *                 the required information.
     * @return A {@link com.stratio.meta.common.result.Result} with the validation result.
     */
    @Override
    public Result validate(MetadataManager metadata) {
        Result result = validateKeyspaceAndTable(metadata, sessionKeyspace, keyspaceInc, keyspace, tableName);
        if(!result.hasError()) {
            String effectiveKeyspace = getEffectiveKeyspace();

            TableMetadata tableMetadata = metadata.getTableMetadata(effectiveKeyspace, tableName);

            if(optsInc){
                result = validateOptions();
            }

            if(!result.hasError()){
                result = validateAssignments(tableMetadata);
            }

            if(!result.hasError()){
                result = validateWhereClauses(tableMetadata);
            }

        }
        return result;
    }

    private Result validateOptions() {
        Result result = QueryResult.createSuccessQueryResult();
        if (!options.contains("timestamp") && !options.contains("ttl")){
            result = QueryResult.createFailQueryResult("TIMESTAMP and TTL are the only accepted options.");
        }
        return result;
    }

    /**
     * Check that the specified columns exist on the target table
     *
     * @param tableMetadata Table metadata associated with the target table.
     * @return A {@link com.stratio.meta.common.result.Result} with the validation result.
     */
    private Result validateAssignments(TableMetadata tableMetadata) {
        Result result = QueryResult.createSuccessQueryResult();
        for (int index = 0; index < assignments.size(); index++) {
            if (tableMetadata.getColumn(assignments.get(index).getIdent().getIdentifier()) == null) {
                result = QueryResult.createFailQueryResult("Column " + assignments.get(index).getIdent().getIdentifier() + " not found in " + tableMetadata.getName());
                break;
            }
        }
        return result;
    }

    private Result validateWhereClauses(TableMetadata tableMetadata) {
        Result result = QueryResult.createSuccessQueryResult();
        for(Relation rel: whereClauses){
            for(String id: rel.getIdentifiers()){
                boolean found = false;
                for(ColumnMetadata cm: tableMetadata.getColumns()){
                    if(cm.getName().equalsIgnoreCase(id)){
                        found = true;
                        break;
                    }
                }
                if(!found){
                    result = QueryResult.createFailQueryResult("Column " + id + " not found in " + tableMetadata.getName());
                    break;
                }
            }
            if(result.hasError()){
                break;
            }
        }
        return result;
    }

    @Override
    public Tree getPlan(MetadataManager metadataManager, String targetKeyspace) {
        return new Tree();
    }
    
}
{'fraction_non_alphanumeric': 0.09293544457978076, 'fraction_numerical': 0.0010962241169305725, 'mean_word_length': 2.0097140762463344, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5455284', 'n_tokens_mistral': 4212, 'n_tokens_neox': 4052, 'n_words': 1213}