Skip to content

Commit

Permalink
Add IF NOT EXISTS option to CREATE CLASS
Browse files Browse the repository at this point in the history
Related to: #3597
  • Loading branch information
luigidellaquila committed Nov 9, 2016
1 parent f889111 commit 9588453
Show file tree
Hide file tree
Showing 9 changed files with 2,362 additions and 2,128 deletions.
5 changes: 5 additions & 0 deletions core/src/main/grammar/OrientSQL.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ TOKEN:
< SERVER: ( "S" | "s") ( "E" | "e") ( "R" | "r") ( "V" | "v") ( "E" | "e") ( "R" | "r") >
|
< SYNC: ( "S" | "s") ( "Y" | "y") ( "N" | "n") ( "C" | "c") >
|
< EXISTS: ( "E" | "e" ) ( "X" | "x" ) ( "i" | "I" ) ( "s" | "S" ) ( "t" | "T" ) ( "s" | "S" ) >
|
< THIS: "@" ( ( "t" | "T" ) ( "h" | "H" ) ( "i" | "I" ) ( "s" | "S" ) ) >
|
Expand Down Expand Up @@ -814,6 +816,8 @@ OIdentifier Identifier():
|
token = <SYNC>
|
token = <EXISTS>
|
quotedToken = <QUOTED_IDENTIFIER>
) {

Expand Down Expand Up @@ -3774,6 +3778,7 @@ OCreateClassStatement CreateClassStatement():
<CREATE> <CLASS>
(
jjtThis.name = Identifier()
[ <IF> <NOT> <EXISTS> { jjtThis.ifNotExists = true; }]
[
<EXTENDS> lastIdentifier = Identifier() { jjtThis.superclasses = new ArrayList<OIdentifier>(); jjtThis.superclasses.add(lastIdentifier); }
(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,26 @@

/**
* SQL CREATE CLASS command: Creates a new property in the target class.
*
*
* @author Luca Garulli (l.garulli--(at)--orientdb.com)
*
*/
@SuppressWarnings("unchecked")
public class OCommandExecutorSQLCreateClass extends OCommandExecutorSQLAbstract implements OCommandDistributedReplicateRequest {
@SuppressWarnings("unchecked") public class OCommandExecutorSQLCreateClass extends OCommandExecutorSQLAbstract
implements OCommandDistributedReplicateRequest {
public static final String KEYWORD_CREATE = "CREATE";
public static final String KEYWORD_CLASS = "CLASS";
public static final String KEYWORD_EXTENDS = "EXTENDS";
public static final String KEYWORD_ABSTRACT = "ABSTRACT";
public static final String KEYWORD_CLUSTER = "CLUSTER";
public static final String KEYWORD_CLUSTERS = "CLUSTERS";
public static final String KEYWORD_IF = "IF";
public static final String KEYWORD_NOT = "NOT";
public static final String KEYWORD_EXISTS = "EXISTS";

private String className;
private String className;
private boolean ifNotExists = false;
private List<OClass> superClasses = new ArrayList<OClass>();
private int[] clusterIds;
private Integer clusters = null;
private int[] clusterIds;
private Integer clusters = null;

public OCommandExecutorSQLCreateClass parse(final OCommandRequest iRequest) {
final OCommandRequestText textRequest = (OCommandRequestText) iRequest;
Expand Down Expand Up @@ -83,8 +86,8 @@ public OCommandExecutorSQLCreateClass parse(final OCommandRequest iRequest) {
throw new OCommandSQLParsingException("Expected <class>", parserText, oldPos);

className = word.toString();
if(this.preParsedStatement!=null){
className = ((OCreateClassStatement)preParsedStatement).name.getStringValue();
if (this.preParsedStatement != null) {
className = ((OCreateClassStatement) preParsedStatement).name.getStringValue();
}
if (className == null)
throw new OCommandSQLParsingException("Expected <class>", parserText, oldPos);
Expand Down Expand Up @@ -156,9 +159,23 @@ else if (Character.isLetterOrDigit(ch))
parserText, oldPos);

clusters = Integer.parseInt(word.toString());
} else if (k.equals(KEYWORD_ABSTRACT))
} else if (k.equals(KEYWORD_ABSTRACT)) {
clusterIds = new int[] { -1 };
else
} else if (k.equals(KEYWORD_IF)) {
oldPos = pos;
pos = nextWord(parserText, parserTextUpperCase, oldPos, word, false, " =><()");
if (!word.toString().equalsIgnoreCase(KEYWORD_NOT)) {
throw new OCommandSQLParsingException(
"Syntax error after IF for class " + className + ". Expected NOT. Use " + getSyntax(), parserText, oldPos);
}
oldPos = pos;
pos = nextWord(parserText, parserTextUpperCase, oldPos, word, false, " =><()");
if (!word.toString().equalsIgnoreCase(KEYWORD_EXISTS)) {
throw new OCommandSQLParsingException(
"Syntax error after IF NOT for class " + className + ". Expected EXISTS. Use " + getSyntax(), parserText, oldPos);
}
ifNotExists = true;
} else
throw new OCommandSQLParsingException("Invalid keyword: " + k);

oldPos = pos;
Expand All @@ -171,19 +188,17 @@ else if (Character.isLetterOrDigit(ch))
}
}

}finally{
} finally {
textRequest.setText(originalQuery);
}
return this;
}

@Override
public long getDistributedTimeout() {
@Override public long getDistributedTimeout() {
return OGlobalConfiguration.DISTRIBUTED_COMMAND_QUICK_TASK_SYNCH_TIMEOUT.getValueAsLong();
}

@Override
public QUORUM_TYPE getQuorumType() {
@Override public QUORUM_TYPE getQuorumType() {
return QUORUM_TYPE.ALL;
}

Expand All @@ -196,26 +211,26 @@ public Object execute(final Map<Object, Object> iArgs) {

final ODatabaseDocument database = getDatabase();

if (clusters != null)
database.getMetadata().getSchema().createClass(className, clusters, superClasses.toArray(new OClass[0]));
else
database.getMetadata().getSchema().createClass(className, clusterIds, superClasses.toArray(new OClass[0]));
boolean alreadyExists = database.getMetadata().getSchema().existsClass(className);
if (!alreadyExists || !ifNotExists) {
if (clusters != null)
database.getMetadata().getSchema().createClass(className, clusters, superClasses.toArray(new OClass[0]));
else
database.getMetadata().getSchema().createClass(className, clusterIds, superClasses.toArray(new OClass[0]));
}

return database.getMetadata().getSchema().getClasses().size();
}

@Override
public String getSyntax() {
return "CREATE CLASS <class> [EXTENDS <super-class> [,<super-class2>*] ] [CLUSTER <clusterId>*] [CLUSTERS <total-cluster-number>] [ABSTRACT]";
@Override public String getSyntax() {
return "CREATE CLASS <class> [IF NOT EXISTS] [EXTENDS <super-class> [,<super-class2>*] ] [CLUSTER <clusterId>*] [CLUSTERS <total-cluster-number>] [ABSTRACT]";
}

@Override
public String getUndoCommand() {
@Override public String getUndoCommand() {
return "drop class " + className;
}

@Override
public boolean involveSchema() {
@Override public boolean involveSchema() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public class OCreateClassStatement extends ODDLStatement {
*/
public OIdentifier name;

public boolean ifNotExists;

/**
* Direct superclasses for this class
*/
Expand Down Expand Up @@ -48,7 +50,13 @@ public OCreateClassStatement(OrientSql p, int id) {
@Override public OTodoResultSet executeDDL(OCommandContext ctx) {

OSchema schema = ctx.getDatabase().getMetadata().getSchema();
checkNotExistsClass(schema, ctx);
if (schema.existsClass(name.getStringValue())) {
if(ifNotExists){
return new OInternalResultSet();
}else {
throw new OCommandExecutionException("Class " + name + " already exists");
}
}
checkSuperclasses(schema, ctx);

OResultInternal result = new OResultInternal();
Expand Down Expand Up @@ -86,11 +94,6 @@ private OClass[] getSuperClasses(OSchema schema) {
.toArray(new OClass[] {});
}

private void checkNotExistsClass(OSchema schema, OCommandContext ctx) {
if (schema.existsClass(name.getStringValue())) {
throw new OCommandExecutionException("Class " + name + " already exists");
}
}

private void checkSuperclasses(OSchema schema, OCommandContext ctx) {
if (superclasses != null) {
Expand All @@ -105,6 +108,9 @@ private void checkSuperclasses(OSchema schema, OCommandContext ctx) {
@Override public void toString(Map<Object, Object> params, StringBuilder builder) {
builder.append("CREATE CLASS ");
name.toString(params, builder);
if(ifNotExists){
builder.append(" IF NOT EXISTS");
}
if (superclasses != null && superclasses.size() > 0) {
builder.append(" EXTENDS ");
boolean first = true;
Expand Down Expand Up @@ -143,6 +149,7 @@ private void checkSuperclasses(OSchema schema, OCommandContext ctx) {
result.clusters = clusters == null ? null : clusters.stream().map(x -> x.copy()).collect(Collectors.toList());
result.totalClusterNo = totalClusterNo == null ? null : totalClusterNo.copy();
result.abstractClass = abstractClass;
result.ifNotExists = ifNotExists;
return result;
}

Expand All @@ -164,6 +171,9 @@ private void checkSuperclasses(OSchema schema, OCommandContext ctx) {
return false;
if (totalClusterNo != null ? !totalClusterNo.equals(that.totalClusterNo) : that.totalClusterNo != null)
return false;
if(ifNotExists!=that.ifNotExists){
return false;
}

return true;
}
Expand Down
Loading

0 comments on commit 9588453

Please sign in to comment.