Skip to content

Commit

Permalink
Fixed issue #2176
Browse files Browse the repository at this point in the history
  • Loading branch information
lvca committed Mar 31, 2014
1 parent cd905cb commit 3ee4117
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
*/
package com.orientechnologies.orient.core.command;

import java.util.HashMap;
import java.util.Map;

import com.orientechnologies.orient.core.command.script.OCommandExecutorScript;
import com.orientechnologies.orient.core.command.script.OCommandScript;
import com.orientechnologies.orient.core.exception.OCommandExecutionException;
import com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate;
Expand All @@ -27,6 +25,9 @@
import com.orientechnologies.orient.core.sql.query.OSQLAsynchQuery;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;

import java.util.HashMap;
import java.util.Map;

public class OCommandManager {
private Map<String, Class<? extends OCommandRequest>> commandRequesters = new HashMap<String, Class<? extends OCommandRequest>>();
private Map<Class<? extends OCommandRequest>, Class<? extends OCommandExecutor>> commandReqExecMap = new HashMap<Class<? extends OCommandRequest>, Class<? extends OCommandExecutor>>();
Expand All @@ -40,6 +41,7 @@ protected OCommandManager() {
registerExecutor(OSQLSynchQuery.class, OCommandExecutorSQLDelegate.class);
registerExecutor(OCommandSQL.class, OCommandExecutorSQLDelegate.class);
registerExecutor(OCommandSQLResultset.class, OCommandExecutorSQLResultsetDelegate.class);
registerExecutor(OCommandScript.class, OCommandExecutorScript.class);
}

public OCommandManager registerRequester(final String iType, final Class<? extends OCommandRequest> iRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,26 @@
*/
package com.orientechnologies.orient.core.command.script;

import java.util.Map;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

import com.orientechnologies.orient.core.Orient;
import com.orientechnologies.orient.core.command.OCommandContext;
import com.orientechnologies.orient.core.command.OCommandExecutorAbstract;
import com.orientechnologies.orient.core.command.OCommandRequest;
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.db.record.ODatabaseRecord;
import com.orientechnologies.orient.core.db.record.ODatabaseRecordTx;
import com.orientechnologies.orient.core.exception.OCommandExecutionException;
import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper;
import com.orientechnologies.orient.core.sql.OCommandSQL;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;

/**
* Executes Script Commands.
Expand Down Expand Up @@ -58,6 +63,18 @@ public Object executeInContext(final OCommandContext iContext, final Map<Object,
final String language = request.getLanguage();
parserText = request.getText();

if (language.equalsIgnoreCase("SQL"))
// SPECIAL CASE: EXECUTE THE COMMANDS IN SEQUENCE
return executeSQL();
else
return executeJsr223Script(language, iContext, iArgs);
}

public boolean isIdempotent() {
return false;
}

protected Object executeJsr223Script(final String language, final OCommandContext iContext, final Map<Object, Object> iArgs) {
ODatabaseRecord db = ODatabaseRecordThreadLocal.INSTANCE.getIfDefined();
if (db != null && !(db instanceof ODatabaseRecordTx))
db = db.getUnderlying();
Expand Down Expand Up @@ -98,8 +115,47 @@ public Object executeInContext(final OCommandContext iContext, final Map<Object,
}
}

public boolean isIdempotent() {
return false;
// TODO: CREATE A REGULAR JSR223 SCRIPT IMPL
protected Object executeSQL() {
ODatabaseRecord db = ODatabaseRecordThreadLocal.INSTANCE.getIfDefined();
if (db != null && !(db instanceof ODatabaseRecordTx))
db = db.getUnderlying();

final BufferedReader reader = new BufferedReader(new StringReader(parserText));
String lastCommand = "";
Object lastResult = null;
try {
while ((lastCommand = reader.readLine()) != null) {
lastCommand = lastCommand.trim();

if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "let ")) {
final int equalsPos = lastCommand.indexOf('=');
final String variable = lastCommand.substring("let ".length(), equalsPos).trim();
final String cmd = lastCommand.substring(equalsPos + 1).trim();

lastResult = db.command(new OCommandSQL(cmd).setContext(getContext())).execute();

// PUT THE RESULT INTO THE CONTEXT
getContext().setVariable(variable, lastResult);
} else if (lastCommand.equalsIgnoreCase("begin"))
db.begin();
else if (lastCommand.equalsIgnoreCase("commit"))
db.commit();
else if (lastCommand.equalsIgnoreCase("rollback"))
db.rollback();
else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "return ")) {
final String variable = lastCommand.substring("return ".length()).trim();

lastResult = getContext().getVariable(variable);
break;
} else
lastResult = db.command(new OCommandSQL(lastCommand).setContext(getContext())).execute();

}
} catch (IOException e) {
throw new OCommandExecutionException("Error on executing command: " + lastCommand, e);
}
return lastResult;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ public String getName() {

@Override
public void startup() {
if (!enabled)
if (!enabled) {
OCommandManager.instance().unregisterExecutor(OCommandScript.class);
return;
}

OLogManager.instance().info(this,
"Installing Script interpreter. WARN: authenticated clients can execute any kind of code into the server.");

// REGISTER THE SECURE COMMAND SCRIPT
// UNREGISTER THE SECURE COMMAND SCRIPT
OCommandManager.instance().registerExecutor(OCommandScript.class, OCommandExecutorScript.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,66 +19,90 @@
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import com.orientechnologies.orient.core.command.script.OCommandScript;
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.metadata.schema.OType;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.OCommandSQL;

@Test(groups = "sql-delete", sequential = true)
public class SQLCommandsTest {
private ODatabaseDocument database;
private ODatabaseDocument database;

@Parameters(value = "url")
public SQLCommandsTest(String iURL) {
database = new ODatabaseDocumentTx(iURL);
}
@Parameters(value = "url")
public SQLCommandsTest(String iURL) {
database = new ODatabaseDocumentTx(iURL);
}

@Test
public void createProperty() {
database.open("admin", "admin");
@Test
public void createProperty() {
database.open("admin", "admin");

database.command(new OCommandSQL("create property account.timesheet string")).execute();
database.command(new OCommandSQL("create property account.timesheet string")).execute();

Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("timesheet").getType(), OType.STRING);
Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("timesheet").getType(), OType.STRING);

database.close();
}
database.close();
}

@Test(dependsOnMethods = "createProperty")
public void createLinkedClassProperty() {
database.open("admin", "admin");
@Test(dependsOnMethods = "createProperty")
public void createLinkedClassProperty() {
database.open("admin", "admin");

database.command(new OCommandSQL("create property account.knows embeddedmap account")).execute();
database.command(new OCommandSQL("create property account.knows embeddedmap account")).execute();

Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("knows").getType(), OType.EMBEDDEDMAP);
Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("knows").getLinkedClass(), database
.getMetadata().getSchema().getClass("account"));
Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("knows").getType(), OType.EMBEDDEDMAP);
Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("knows").getLinkedClass(), database
.getMetadata().getSchema().getClass("account"));

database.close();
}
database.close();
}

@Test(dependsOnMethods = "createLinkedClassProperty")
public void createLinkedTypeProperty() {
database.open("admin", "admin");
@Test(dependsOnMethods = "createLinkedClassProperty")
public void createLinkedTypeProperty() {
database.open("admin", "admin");

database.command(new OCommandSQL("create property account.tags embeddedlist string")).execute();
database.command(new OCommandSQL("create property account.tags embeddedlist string")).execute();

Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("tags").getType(), OType.EMBEDDEDLIST);
Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("tags").getLinkedType(), OType.STRING);
Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("tags").getType(), OType.EMBEDDEDLIST);
Assert.assertEquals(database.getMetadata().getSchema().getClass("account").getProperty("tags").getLinkedType(), OType.STRING);

database.close();
}
database.close();
}

@Test(dependsOnMethods = "createLinkedTypeProperty")
public void removeProperty() {
database.open("admin", "admin");
@Test(dependsOnMethods = "createLinkedTypeProperty")
public void removeProperty() {
database.open("admin", "admin");

database.command(new OCommandSQL("drop property account.timesheet")).execute();
database.command(new OCommandSQL("drop property account.tags")).execute();
database.command(new OCommandSQL("drop property account.timesheet")).execute();
database.command(new OCommandSQL("drop property account.tags")).execute();

Assert.assertFalse(database.getMetadata().getSchema().getClass("account").existsProperty("timesheet"));
Assert.assertFalse(database.getMetadata().getSchema().getClass("account").existsProperty("tags"));
Assert.assertFalse(database.getMetadata().getSchema().getClass("account").existsProperty("timesheet"));
Assert.assertFalse(database.getMetadata().getSchema().getClass("account").existsProperty("tags"));

database.close();
}
database.close();
}

@Test(dependsOnMethods = "removeProperty")
public void testSQLScript() {
database.open("admin", "admin");

String cmd = "";
cmd += "begin";
cmd += "\nlet a = create vertex set script = true";
cmd += "\nlet b = select from v limit 1";
cmd += "\ncreate edge from $a to $b";
cmd += "\ncommit";
cmd += "\nreturn $a";

Object result = database.command(new OCommandScript("sql", cmd)).execute();

Assert.assertTrue(result instanceof OIdentifiable);
Assert.assertTrue(((OIdentifiable)result).getRecord() instanceof ODocument);
Assert.assertTrue((Boolean) ((ODocument)((OIdentifiable)result).getRecord()).field("script"));

database.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import com.orientechnologies.orient.client.remote.OStorageRemoteThread;
import com.orientechnologies.orient.core.OConstants;
import com.orientechnologies.orient.core.Orient;
import com.orientechnologies.orient.core.command.OCommandManager;
import com.orientechnologies.orient.core.command.OCommandOutputListener;
import com.orientechnologies.orient.core.command.script.OCommandExecutorScript;
import com.orientechnologies.orient.core.command.script.OCommandScript;
Expand Down Expand Up @@ -211,8 +210,6 @@ protected void onBefore() {
properties.put("ignoreErrors", "false");
properties.put("backupCompressionLevel", "9"); // 9 = MAX
properties.put("backupBufferSize", "1048576"); // 1MB

OCommandManager.instance().registerExecutor(OCommandScript.class, OCommandExecutorScript.class);
}

@Override
Expand Down

0 comments on commit 3ee4117

Please sign in to comment.