Package com.orientechnologies.orient.core.sql

Source Code of com.orientechnologies.orient.core.sql.OCommandExecutorSQLInsert

/*
* Copyright 1999-2010 Luca Garulli (l.garulli--at--orientechnologies.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.orientechnologies.orient.core.sql;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.orientechnologies.common.parser.OStringParser;
import com.orientechnologies.orient.core.command.OCommandRequestText;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.exception.OCommandExecutionException;
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.security.ODatabaseSecurityResources;
import com.orientechnologies.orient.core.metadata.security.ORole;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper;

/**
* SQL INSERT command.
*
* @author Luca Garulli
*
*/
public class OCommandExecutorSQLInsert extends OCommandExecutorSQLAbstract {
  public static final String  KEYWORD_INSERT  = "INSERT";
  private static final String  KEYWORD_VALUES  = "VALUES";
  private static final String  KEYWORD_INTO    = "INTO";
  private String              className        = null;
  private String              clusterName      = null;
  private String              indexName        = null;
  private Map<String, Object>  fields;

  @SuppressWarnings("unchecked")
  public OCommandExecutorSQLInsert parse(final OCommandRequestText iRequest) {
    iRequest.getDatabase().checkSecurity(ODatabaseSecurityResources.COMMAND, ORole.PERMISSION_CREATE);

    init(iRequest.getDatabase(), iRequest.getText());

    className = null;
    fields = null;

    StringBuilder word = new StringBuilder();

    int pos = OSQLHelper.nextWord(text, textUpperCase, 0, word, true);
    if (pos == -1 || !word.toString().equals(OCommandExecutorSQLInsert.KEYWORD_INSERT))
      throw new OCommandSQLParsingException("Keyword " + OCommandExecutorSQLInsert.KEYWORD_INSERT + " not found", text, 0);

    pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true);
    if (pos == -1 || !word.toString().equals(KEYWORD_INTO))
      throw new OCommandSQLParsingException("Keyword " + KEYWORD_INTO + " not found", text, 0);

    pos = OSQLHelper.nextWord(text, textUpperCase, pos, word, true);
    if (pos == -1)
      throw new OCommandSQLParsingException("Invalid subject name. Expected cluster, class or index", text, pos);

    String subjectName = word.toString();

    if (subjectName.startsWith(OCommandExecutorSQLAbstract.CLUSTER_PREFIX))
      // CLUSTER
      clusterName = subjectName.substring(OCommandExecutorSQLAbstract.CLUSTER_PREFIX.length());

    else if (subjectName.startsWith(OCommandExecutorSQLAbstract.INDEX_PREFIX))
      // INDEX
      indexName = subjectName.substring(OCommandExecutorSQLAbstract.INDEX_PREFIX.length());

    else {
      // CLASS
      if (subjectName.startsWith(OCommandExecutorSQLAbstract.CLASS_PREFIX))
        subjectName = subjectName.substring(OCommandExecutorSQLAbstract.CLASS_PREFIX.length());

      final OClass cls = database.getMetadata().getSchema().getClass(subjectName);
      if (cls == null)
        throw new OCommandSQLParsingException("Class " + subjectName + " not found in database", text, pos);

      className = cls.getName();
    }

    final int beginFields = OStringParser.jumpWhiteSpaces(text, pos);
    if (beginFields == -1 || text.charAt(beginFields) != '(')
      throw new OCommandSQLParsingException("Set of fields is missed. Example: (name, surname)", text, pos);

    final int endFields = text.indexOf(')', beginFields + 1);
    if (endFields == -1)
      throw new OCommandSQLParsingException("Missed closed brace", text, beginFields);

    final ArrayList<String> fieldNames = new ArrayList<String>();
    OStringSerializerHelper.getParameters(text, beginFields, fieldNames);
    if (fieldNames.size() == 0)
      throw new OCommandSQLParsingException("Set of fields is empty. Example: (name, surname)", text, endFields);

    // REMOVE QUOTATION MARKS IF ANY
    for (int i = 0; i < fieldNames.size(); ++i)
      fieldNames.set(i, OStringSerializerHelper.removeQuotationMarks(fieldNames.get(i)));

    pos = OSQLHelper.nextWord(text, textUpperCase, endFields + 1, word, true);
    if (pos == -1 || !word.toString().equals(KEYWORD_VALUES))
      throw new OCommandSQLParsingException("Missed VALUES keyword", text, endFields);

    final int beginValues = OStringParser.jumpWhiteSpaces(text, pos + 1);
    if (pos == -1 || text.charAt(beginValues) != '(')
      throw new OCommandSQLParsingException("Set of values is missed. Example: ('Bill', 'Stuart', 300)", text, pos);

    final int endValues = text.lastIndexOf(')');
    if (endValues == -1)
      throw new OCommandSQLParsingException("Missed closed brace", text, beginValues);

    final List<String> values = OStringSerializerHelper.smartSplit(text.substring(beginValues + 1, endValues), ',');

    if (values.size() == 0)
      throw new OCommandSQLParsingException("Set of values is empty. Example: ('Bill', 'Stuart', 300)", text, beginValues);

    if (values.size() != fieldNames.size())
      throw new OCommandSQLParsingException("Fields not match with values", text, beginValues);

    // TRANSFORM FIELD VALUES
    final Object[] fieldValues = new Object[values.size()];
    for (int i = 0; i < values.size(); ++i)
      fieldValues[i] = OSQLHelper.parseValue(database, this, OStringSerializerHelper.decode(values.get(i).trim()));

    fields = new LinkedHashMap<String, Object>();
    for (int i = 0; i < fieldNames.size(); ++i)
      fields.put(fieldNames.get(i), fieldValues[i]);

    return this;
  }

  /**
   * Execute the INSERT and return the ODocument object created.
   */
  public Object execute(final Map<Object, Object> iArgs) {
    if (fields == null)
      throw new OCommandExecutionException("Can't execute the command because it hasn't been parsed yet");

    if (indexName != null) {
      final OIndex index = database.getMetadata().getIndexManager().getIndex(indexName);
      if (index == null)
        throw new OCommandExecutionException("Target index '" + indexName + "' not found");

      // BIND VALUES
      index.put(fields.get(KEYWORD_KEY), (OIdentifiable) fields.get(KEYWORD_RID));
      return null;
    } else {
      // CREATE NEW DOCUMENT
      ODocument doc = className != null ? new ODocument(database, className) : new ODocument(database);

      OSQLHelper.bindParameters(doc, fields, iArgs);

      if (clusterName != null)
        doc.save(clusterName);
      else
        doc.save();
      return doc;
    }
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.sql.OCommandExecutorSQLInsert

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.