<commit_before>/*
 *
 *  *  Copyright 2015 Orient Technologies LTD (info(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.
 *  *
 *  * For more information: http://www.orientechnologies.com
 *
 */
package com.orientechnologies.orient.core.sql;

import com.orientechnologies.orient.core.command.OCommandRequest;
import com.orientechnologies.orient.core.command.OCommandRequestText;
import com.orientechnologies.orient.core.command.OCommandResultListener;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.db.record.ORecordOperation;
import com.orientechnologies.orient.core.exception.OSecurityException;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.security.ORole;
import com.orientechnologies.orient.core.metadata.security.ORule;
import com.orientechnologies.orient.core.query.live.OLiveQueryHook;
import com.orientechnologies.orient.core.query.live.OLiveQueryListener;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.query.OLiveResultListener;
import com.orientechnologies.orient.core.sql.query.OLiveResultSet;
import com.orientechnologies.orient.core.sql.query.OResultSet;

import java.util.Map;
import java.util.Random;

/**
 * @author <NAME>
 */
public class OCommandExecutorSQLLiveSelect extends OCommandExecutorSQLSelect implements OLiveQueryListener {
  public static final String KEYWORD_LIVE_SELECT = "LIVE SELECT";
  private OLiveResultSet     liveResultSet;
  private ODatabaseDocument  execDb;
  private int                token;
  static Random              random              = new Random();

  protected String           unsubscribeToken;

  public OCommandExecutorSQLLiveSelect() {

  }

  public Object execute(final Map<Object, Object> iArgs) {
    try {

      execDb = ((ODatabaseDocumentTx) getDatabase()).copy();

      synchronized (random) {
        token = random.nextInt();// TODO do something better ;-)!
      }
      subscribeToLiveQuery(token);
      bindDefaultContextVariables();

      if (iArgs != null)
      // BIND ARGUMENTS INTO CONTEXT TO ACCESS FROM ANY POINT (EVEN FUNCTIONS)
      {
        for (Map.Entry<Object, Object> arg : iArgs.entrySet()) {
          context.setVariable(arg.getKey().toString(), arg.getValue());
        }
      }

      if (timeoutMs > 0) {
        getContext().beginExecution(timeoutMs, timeoutStrategy);
      }

      ODocument result = new ODocument();
      result.field("token", token);// TODO change this name...?

      ((OResultSet) getResult()).add(result);
      return getResult();
    } finally {
      if (request != null && request.getResultListener() != null) {
        request.getResultListener().end();
      }
    }
  }

  private void subscribeToLiveQuery(Integer token) {
    OLiveQueryHook.subscribe(token, this);
  }

  public void onLiveResult(ORecordOperation iOp) {

    ODocument doc = new ODocument();
    OIdentifiable value = iOp.getRecord();

    if (!matchesTarget(value)) {
      return;
    }
    if (!matchesFilters(value)) {
      return;
    }
    if (!checkSecurity(value)) {
      return;
    }

    OCommandResultListener listener = request.getResultListener();
    if (listener instanceof OLiveResultListener) {
      ((OLiveResultListener) listener).onLiveResult(token, iOp);
    }
  }

  private boolean checkSecurity(OIdentifiable value) {
    try {
      // TODO check this!
      execDb.checkSecurity(ORule.ResourceGeneric.CLASS, ORole.PERMISSION_READ, ((ODocument) value.getRecord()).getClassName());
    } catch (OSecurityException e) {
      return false;
    }
    return true;
  }

  private boolean matchesFilters(OIdentifiable value) {
    return true;// TODO
  }

  private boolean matchesTarget(OIdentifiable value) {
    if (!(value instanceof ODocument)) {
      return false;
    }<commit_msg>finished filter implementation on live query<commit_after>/*
 *
 *  *  Copyright 2015 Orient Technologies LTD (info(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.
 *  *
 *  * For more information: http://www.orientechnologies.com
 *
 */
package com.orientechnologies.orient.core.sql;

import com.orientechnologies.orient.core.command.OCommandRequest;
import com.orientechnologies.orient.core.command.OCommandRequestText;
import com.orientechnologies.orient.core.command.OCommandResultListener;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.db.record.ORecordOperation;
import com.orientechnologies.orient.core.exception.OSecurityException;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.security.ORole;
import com.orientechnologies.orient.core.metadata.security.ORule;
import com.orientechnologies.orient.core.query.live.OLiveQueryHook;
import com.orientechnologies.orient.core.query.live.OLiveQueryListener;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.query.OLiveResultListener;
import com.orientechnologies.orient.core.sql.query.OLiveResultSet;
import com.orientechnologies.orient.core.sql.query.OResultSet;

import java.util.Map;
import java.util.Random;

/**
 * @author <NAME>
 */
public class OCommandExecutorSQLLiveSelect extends OCommandExecutorSQLSelect implements OLiveQueryListener {
  public static final String KEYWORD_LIVE_SELECT = "LIVE SELECT";
  private OLiveResultSet     liveResultSet;
  private ODatabaseDocument  execDb;
  private int                token;
  static Random              random              = new Random();

  protected String           unsubscribeToken;

  public OCommandExecutorSQLLiveSelect() {

  }

  public Object execute(final Map<Object, Object> iArgs) {
    try {

      execDb = ((ODatabaseDocumentTx) getDatabase()).copy();

      synchronized (random) {
        token = random.nextInt();// TODO do something better ;-)!
      }
      subscribeToLiveQuery(token);
      bindDefaultContextVariables();

      if (iArgs != null)
      // BIND ARGUMENTS INTO CONTEXT TO ACCESS FROM ANY POINT (EVEN FUNCTIONS)
      {
        for (Map.Entry<Object, Object> arg : iArgs.entrySet()) {
          context.setVariable(arg.getKey().toString(), arg.getValue());
        }
      }

      if (timeoutMs > 0) {
        getContext().beginExecution(timeoutMs, timeoutStrategy);
      }

      ODocument result = new ODocument();
      result.field("token", token);// TODO change this name...?

      ((OResultSet) getResult()).add(result);
      return getResult();
    } finally {
      if (request != null && request.getResultListener() != null) {
        request.getResultListener().end();
      }
    }
  }

  private void subscribeToLiveQuery(Integer token) {
    OLiveQueryHook.subscribe(token, this);
  }

  public void onLiveResult(ORecordOperation iOp) {

    ODocument doc = new ODocument();
    OIdentifiable value = iOp.getRecord();

    if (!matchesTarget(value)) {
      return;
    }
    if (!matchesFilters(value)) {
      return;
    }
    if (!checkSecurity(value)) {
      return;
    }

    OCommandResultListener listener = request.getResultListener();
    if (listener instanceof OLiveResultListener) {
      ((OLiveResultListener) listener).onLiveResult(token, iOp);
    }
  }

  private boolean checkSecurity(OIdentifiable value) {
    try {
      // TODO check this!
      execDb.checkSecurity(ORule.ResourceGeneric.CLASS, ORole.PERMISSION_READ, ((ODocument) value.getRecord()).getClassName());
    } catch (OSecurityException e) {
      return false;
    }
    return true;
  }

  private boolean matchesFilters(OIdentifiable value) {
    if (this.compiledFilter == null || this.compiledFilter.getRootCondition() == null) {
      return true;
    }
    if (!(value instanceof ODocument)) {
      value = value.getRecord();
    }
    return !(Boolean.FALSE.equals(compiledFilter.evaluate((ODocument) value, (ODocument) value, getContext())));
  }

  private boolean matchesTarget(OIdentifiable value) {
    if (!(value instanceof ODocument)) {
      return false;
    }
{'fraction_non_alphanumeric': 0.10542797494780794, 'fraction_numerical': 0.0018789144050104384, 'mean_word_length': 3.577639751552795, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, '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': '5016828', 'n_tokens_mistral': 2799, 'n_tokens_neox': 2742, 'n_words': 627}