org.opencypher.v9_0.parser.AdministrationCommand.scala Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) Neo4j Sweden AB (http://neo4j.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 org.opencypher.v9_0.parser
import org.opencypher.v9_0.ast
import org.opencypher.v9_0.ast.IndefiniteWait
import org.opencypher.v9_0.ast.NoWait
import org.opencypher.v9_0.ast.TimeoutAfter
import org.opencypher.v9_0.ast.WaitUntilComplete
import org.opencypher.v9_0.expressions.Expression
import org.opencypher.v9_0.expressions.Parameter
import org.opencypher.v9_0.util.InputPosition
import org.parboiled.scala.Parser
import org.parboiled.scala.Rule0
import org.parboiled.scala.Rule1
import org.parboiled.scala.Rule2
import org.parboiled.scala.Rule3
import org.parboiled.scala.Rule4
import org.parboiled.scala.group
//noinspection ConvertibleToMethodValue
// Can't convert since that breaks parsing
trait AdministrationCommand extends Parser
with GraphSelection
with CommandHelper
with Base {
def AdministrationCommand: Rule1[ast.AdministrationCommand] = rule("Administration statement") {
optional(UseGraph) ~~ (MultiDatabaseAdministrationCommand | PrivilegeAdministrationCommand | UserAndRoleAdministrationCommand) ~~> ((use, command) => command.withGraph(use))
}
def MultiDatabaseAdministrationCommand: Rule1[ast.AdministrationCommand] = rule("MultiDatabase administration statement") {
optional(keyword("CATALOG")) ~~ (ShowDatabase | CreateDatabase | DropDatabase | StartDatabase | StopDatabase)
}
def UserAndRoleAdministrationCommand: Rule1[ast.AdministrationCommand] = rule("Security role and user administration statement") {
optional(keyword("CATALOG")) ~~ (ShowRoles | CreateRole | DropRole | ShowUsers | ShowCurrentUser | CreateUser | DropUser | AlterUser | SetOwnPassword)
}
def PrivilegeAdministrationCommand: Rule1[ast.AdministrationCommand] = rule("Security privilege administration statement") {
optional(keyword("CATALOG")) ~~ (ShowPrivileges | GrantCommand | DenyCommand | RevokeCommand)
}
def GrantCommand: Rule1[ast.AdministrationCommand] = rule("Security privilege grant statement") {
GrantRole | GrantDatabasePrivilege | GrantGraphPrivilege | GrantDbmsPrivilege
}
def DenyCommand: Rule1[ast.AdministrationCommand] = rule("Security privilege deny statement") {
DenyDatabasePrivilege | DenyGraphPrivilege | DenyDbmsPrivilege
}
def RevokeCommand: Rule1[ast.AdministrationCommand] = rule("Security privilege revoke statement") {
RevokeRole | RevokeGraphPrivilege | RevokeDatabasePrivilege | RevokeDbmsPrivilege
}
// User management commands
def ShowUsers: Rule1[ast.ShowUsers] = rule("SHOW USERS") {
keyword("SHOW USERS") ~~ optional(ShowCommandClauses) ~~>> (ast.ShowUsers(_))
}
def ShowCurrentUser: Rule1[ast.ShowCurrentUser] = rule("SHOW CURRENT USER") {
keyword("SHOW CURRENT USER") ~~ optional(ShowCommandClauses) ~~>> (ast.ShowCurrentUser(_))
}
def CreateUser: Rule1[ast.CreateUser] = rule("CREATE USER") {
// CREATE [OR REPLACE] USER username [IF NOT EXISTS] SET [PLAINTEXT | ENCRYPTED] PASSWORD stringLiteralPassword|parameterPassword [{SET PASSWORD CHANGE [NOT] REQUIRED} | {SET STATUS SUSPENDED|ACTIVE} | {SET HOME DATABASE name}]*
group(CreateUserStart ~~ SetPassword ~~ optional(UserOptions)) ~~>>
((userName, ifExistsDo, isEncryptedPassword, initialPassword, userOptions) => {
val createUserOptions = userOptions.map {
// Since we in the prettifier adds `CHANGE REQUIRED` if omitted,
// we should parse them to the same thing (as we did before adding UserOptions)
case ast.UserOptions(None, s, d) => ast.UserOptions(Some(true), s, d)
case u => u
}.getOrElse(ast.UserOptions(Some(true), None, None))
ast.CreateUser(userName, isEncryptedPassword, initialPassword, createUserOptions, ifExistsDo)
})
}
def CreateUserStart: Rule2[Either[String, Parameter], ast.IfExistsDo] = {
// returns: userName, IfExistsDo
group(keyword("CREATE OR REPLACE USER") ~~ SymbolicNameOrStringParameter ~~ keyword("IF NOT EXISTS") ~> (_ => ast.IfExistsInvalidSyntax)) |
group(keyword("CREATE OR REPLACE USER") ~~ SymbolicNameOrStringParameter ~> (_ => ast.IfExistsReplace)) |
group(keyword("CREATE USER") ~~ SymbolicNameOrStringParameter ~~ keyword("IF NOT EXISTS") ~> (_ => ast.IfExistsDoNothing)) |
group(keyword("CREATE USER") ~~ SymbolicNameOrStringParameter ~> (_ => ast.IfExistsThrowError))
}
def DropUser: Rule1[ast.DropUser] = rule("DROP USER") {
group(keyword("DROP USER") ~~ SymbolicNameOrStringParameter ~~ keyword("IF EXISTS")) ~~>> (ast.DropUser(_, ifExists = true)) |
group(keyword("DROP USER") ~~ SymbolicNameOrStringParameter) ~~>> (ast.DropUser(_, ifExists = false))
}
def AlterUser: Rule1[ast.AlterUser] = rule("ALTER USER") {
// ALTER USER username [IF EXISTS] SET [PLAINTEXT | ENCRYPTED] PASSWORD stringLiteralPassword|parameterPassword [{SET PASSWORD CHANGE [NOT] REQUIRED} | {SET STATUS SUSPENDED|ACTIVE} | {SET HOME DATABASE name}]*
group(AlterUserStart ~~ SetPassword ~~ optional(UserOptions)) ~~>>
((userName, ifExists, isEncryptedPassword, initialPassword, userOptions) => ast.AlterUser(userName, Some(isEncryptedPassword), Some(initialPassword), userOptions.getOrElse(ast.UserOptions(None, None, None)), ifExists)) |
//
// ALTER USER username [IF EXISTS] [{SET PASSWORD CHANGE [NOT] REQUIRED} | {SET STATUS SUSPENDED|ACTIVE} | {SET HOME DATABASE name}]+
group(AlterUserStart ~~ UserOptionsWithSetPart) ~~>> ((userName, ifExists, userOptions) => ast.AlterUser(userName, None, None, userOptions, ifExists)) |
// ALTER USER username [IF EXISTS] REMOVE HOME DATABASE
group(AlterUserStart ~~ keyword("REMOVE HOME DATABASE")) ~~>> ((userName, ifExists) => ast.AlterUser(userName, None, None, ast.UserOptions(None, None, Some(Left(null))), ifExists))
}
def AlterUserStart: Rule2[Either[String, Parameter], Boolean] = {
// returns: userName, IfExists
group(keyword("ALTER USER") ~~ SymbolicNameOrStringParameter ~~ keyword("IF EXISTS") ~> (_ => true)) |
group(keyword("ALTER USER") ~~ SymbolicNameOrStringParameter ~> (_ => false))
}
def SetOwnPassword: Rule1[ast.SetOwnPassword] = rule("ALTER CURRENT USER SET PASSWORD") {
// ALTER CURRENT USER SET PASSWORD FROM stringLiteralPassword|parameterPassword TO stringLiteralPassword|parameterPassword
group(keyword("ALTER CURRENT USER SET PASSWORD FROM") ~~ PasswordExpression ~~ keyword("TO") ~~ PasswordExpression) ~~>>
((currentPassword, newPassword) => ast.SetOwnPassword(newPassword, currentPassword))
}
def SetPassword: Rule2[Boolean, Expression] = rule("set encrypted or plaintext password") {
// returns: isEncryptedPassword
group(
group(keyword("SET") ~~ optional(keyword("PLAINTEXT")) ~~ keyword("PASSWORD") ~> (_ => false)) |
group(keyword("SET ENCRYPTED PASSWORD") ~> (_ => true))
) ~~ PasswordExpression
}
def PasswordExpression: Rule1[Expression] = group(SensitiveStringLiteral | SensitiveStringParameter)
def UserOptions: Rule1[ast.UserOptions] =
RequirePasswordChangeNoSetKeyword ~~ SetStatus ~~ SetHomeDatabase ~~> ((password, status, database) => ast.UserOptions(Some(password), Some(status), Some(database))) |
RequirePasswordChangeNoSetKeyword ~~ SetHomeDatabase ~~ SetStatus ~~> ((password, database, status) => ast.UserOptions(Some(password), Some(status), Some(database))) |
RequirePasswordChangeNoSetKeyword ~~ SetStatus ~~> ((password, status) => ast.UserOptions(Some(password), Some(status), None)) |
RequirePasswordChangeNoSetKeyword ~~ SetHomeDatabase ~~> ((password, database) => ast.UserOptions(Some(password), None, Some(database))) |
RequirePasswordChangeNoSetKeyword ~~> (password => ast.UserOptions(Some(password), None, None)) |
UserOptionsWithSetPart
def UserOptionsWithSetPart: Rule1[ast.UserOptions] =
RequirePasswordChange ~~ SetStatus ~~ SetHomeDatabase ~~> ((password, status, database) => ast.UserOptions(Some(password), Some(status), Some(database))) |
RequirePasswordChange ~~ SetHomeDatabase ~~ SetStatus ~~> ((password, database, status) => ast.UserOptions(Some(password), Some(status), Some(database))) |
SetStatus ~~ RequirePasswordChange ~~ SetHomeDatabase ~~> ((status, password, database) => ast.UserOptions(Some(password), Some(status), Some(database))) |
SetStatus ~~ SetHomeDatabase ~~ RequirePasswordChange ~~> ((status, database, password) => ast.UserOptions(Some(password), Some(status), Some(database))) |
SetHomeDatabase ~~ RequirePasswordChange ~~ SetStatus ~~> ((database, password, status) => ast.UserOptions(Some(password), Some(status), Some(database))) |
SetHomeDatabase ~~ SetStatus ~~ RequirePasswordChange ~~> ((database, status, password) => ast.UserOptions(Some(password), Some(status), Some(database))) |
RequirePasswordChange ~~ SetStatus ~~> ((password, status) => ast.UserOptions(Some(password), Some(status), None)) |
RequirePasswordChange ~~ SetHomeDatabase ~~> ((password, database) => ast.UserOptions(Some(password), None, Some(database))) |
SetStatus ~~ RequirePasswordChange ~~> ((status, password) => ast.UserOptions(Some(password), Some(status), None)) |
SetStatus ~~ SetHomeDatabase ~~> ((status, database) => ast.UserOptions(None, Some(status), Some(database))) |
SetHomeDatabase ~~ RequirePasswordChange ~~> ((database, password) => ast.UserOptions(Some(password), None, Some(database))) |
SetHomeDatabase ~~ SetStatus ~~> ((database, status) => ast.UserOptions(None, Some(status), Some(database))) |
RequirePasswordChange ~~> (password => ast.UserOptions(Some(password), None, None)) |
SetStatus ~~> (status => ast.UserOptions(None, Some(status), None)) |
SetHomeDatabase ~~> (database => ast.UserOptions(None, None, Some(database)))
def RequirePasswordChangeNoSetKeyword: Rule1[Boolean] =
keyword("CHANGE NOT REQUIRED") ~>>> (_ => _ => false) |
keyword("CHANGE REQUIRED") ~>>> (_ => _ => true)
//noinspection MutatorLikeMethodIsParameterless
def RequirePasswordChange: Rule1[Boolean] =
keyword("SET PASSWORD CHANGE NOT REQUIRED") ~>>> (_ => _ => false) |
keyword("SET PASSWORD CHANGE REQUIRED") ~>>> (_ => _ => true)
def SetStatus: Rule1[Boolean] =
keyword("SET STATUS SUSPENDED") ~>>> (_ => _ => true) |
keyword("SET STATUS ACTIVE") ~>>> (_ => _ => false)
def SetHomeDatabase: Rule1[Either[String, Parameter]] =
keyword("SET HOME DATABASE") ~~ SymbolicDatabaseNameOrStringParameter
// Role management commands
def ShowRoles: Rule1[ast.ShowRoles] = rule("SHOW ROLES") {
//SHOW [ ALL | POPULATED ] ROLES WITH USERS
group(ShowAllRoles ~~ keyword("WITH USERS") ~~ optional(ShowCommandClauses)) ~~>> (ast.ShowRoles(withUsers = true, _, _)) |
// SHOW [ ALL | POPULATED ] ROLES
group(ShowAllRoles ~~ optional(ShowCommandClauses)) ~~>> (ast.ShowRoles(withUsers = false, _, _))
}
private def ShowAllRoles: Rule1[Boolean] = rule("return true for SHOW ALL ROLES, false for SHOW POPULATED ROLES") {
keyword("SHOW POPULATED ROLES") ~~~> (_ => false) |
group(keyword("SHOW") ~~ optional(keyword("ALL")) ~~ keyword("ROLES")) ~~~> (_ => true)
}
def CreateRole: Rule1[ast.CreateRole] = rule("CREATE ROLE") {
group(CreateRoleStart ~~ optional(keyword("AS COPY OF") ~~ SymbolicNameOrStringParameter)) ~~>> ((roleName, ifExistsDo, from) => ast.CreateRole(roleName, from, ifExistsDo))
}
private def CreateRoleStart: Rule2[Either[String, Parameter], ast.IfExistsDo] = {
// returns: roleName, IfExistsDo
group(keyword("CREATE OR REPLACE ROLE") ~~ SymbolicNameOrStringParameter ~~ keyword("IF NOT EXISTS") ~> (_ => ast.IfExistsInvalidSyntax)) |
group(keyword("CREATE OR REPLACE ROLE") ~~ SymbolicNameOrStringParameter ~> (_ => ast.IfExistsReplace)) |
group(keyword("CREATE ROLE") ~~ SymbolicNameOrStringParameter ~~ keyword("IF NOT EXISTS") ~> (_ => ast.IfExistsDoNothing)) |
group(keyword("CREATE ROLE") ~~ SymbolicNameOrStringParameter ~> (_ => ast.IfExistsThrowError))
}
def DropRole: Rule1[ast.DropRole] = rule("DROP ROLE") {
group(keyword("DROP ROLE") ~~ SymbolicNameOrStringParameter ~~ keyword("IF EXISTS")) ~~>> (ast.DropRole(_, ifExists = true)) |
group(keyword("DROP ROLE") ~~ SymbolicNameOrStringParameter) ~~>> (ast.DropRole(_, ifExists = false))
}
def GrantRole: Rule1[ast.GrantRolesToUsers] = rule("GRANT ROLE") {
group(keyword("GRANT") ~~ RoleKeyword ~~ SymbolicNameOrStringParameterList ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>> (ast.GrantRolesToUsers(_, _))
}
def RevokeRole: Rule1[ast.RevokeRolesFromUsers] = rule("REVOKE ROLE") {
group(keyword("REVOKE") ~~ RoleKeyword ~~ SymbolicNameOrStringParameterList ~~ keyword("FROM") ~~ SymbolicNameOrStringParameterList) ~~>> (ast.RevokeRolesFromUsers(_, _))
}
// Privilege commands
def ShowPrivileges: Rule1[ast.ReadAdministrationCommand] = rule("SHOW PRIVILEGES") {
group(keyword("SHOW") ~~ ScopeForShowPrivileges ~~ asCommand ~~ optional(ShowCommandClauses) ~~>> ((scope, revoke, yld) => ast.ShowPrivilegeCommands(scope, revoke, yld))) |
group(keyword("SHOW") ~~ ScopeForShowPrivileges ~~ optional(ShowCommandClauses) ~~>> ((scope, yld) => ast.ShowPrivileges(scope, yld)))
}
private def ScopeForShowPrivileges: Rule1[ast.ShowPrivilegeScope] = rule("show privilege scope") {
group(RoleKeyword ~~ SymbolicNameOrStringParameterList ~~ PrivilegeKeyword) ~~>> (ast.ShowRolesPrivileges(_)) |
group(UserKeyword ~~ SymbolicNameOrStringParameterList ~~ PrivilegeKeyword) ~~>> (ast.ShowUsersPrivileges(_)) |
group(UserKeyword ~~ PrivilegeKeyword) ~~~> ast.ShowUserPrivileges(None) |
optional(keyword("ALL")) ~~ PrivilegeKeyword ~~~> ast.ShowAllPrivileges()
}
private def asCommand: Rule1[Boolean] = rule("AS COMMANDS") {
group(keyword("AS") ~~ CommandKeyword) ~> (_ => false) |
group(keyword("AS REVOKE") ~~ CommandKeyword) ~> (_ => true)
}
//` ... ON DBMS TO role`
def GrantDbmsPrivilege: Rule1[ast.GrantPrivilege] = rule("GRANT dbms privileges") {
group(keyword("GRANT") ~~ DbmsAction ~~ keyword("ON DBMS TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((dbmsAction, grantees) => pos => ast.GrantPrivilege.dbmsAction(dbmsAction, grantees, List(ast.AllQualifier()(pos)))(pos)) |
group(keyword("GRANT") ~~ QualifiedDbmsAction ~~ keyword("ON DBMS TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((qualifier, dbmsAction, grantees) => ast.GrantPrivilege.dbmsAction( dbmsAction, grantees, qualifier ))
}
def DenyDbmsPrivilege: Rule1[ast.DenyPrivilege] = rule("DENY dbms privileges") {
group(keyword("DENY") ~~ DbmsAction ~~ keyword("ON DBMS TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((dbmsAction, grantees) => ast.DenyPrivilege.dbmsAction( dbmsAction, grantees )) |
group(keyword("DENY") ~~ QualifiedDbmsAction ~~ keyword("ON DBMS TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((qualifier, dbmsAction, grantees) => ast.DenyPrivilege.dbmsAction( dbmsAction, grantees, qualifier ))
}
def RevokeDbmsPrivilege: Rule1[ast.RevokePrivilege] = rule("REVOKE dbms privileges") {
group(RevokeType ~~ DbmsAction ~~ keyword("ON DBMS FROM") ~~ SymbolicNameOrStringParameterList) ~~>>
((revokeType, dbmsAction, grantees) => ast.RevokePrivilege.dbmsAction(dbmsAction, grantees, revokeType)) |
group(RevokeType ~~ QualifiedDbmsAction ~~ keyword("ON DBMS FROM") ~~ SymbolicNameOrStringParameterList) ~~>>
((revokeType, qualifier, dbmsAction, grantees) => ast.RevokePrivilege.dbmsAction(dbmsAction, grantees, revokeType, qualifier))
}
//` ... ON DATABASE foo TO role`
def GrantDatabasePrivilege: Rule1[ast.GrantPrivilege] = rule("GRANT database privileges") {
group(keyword("GRANT") ~~ QualifiedDatabaseAction ~~ Database ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((qualifier, databaseAction, scope, grantees) => ast.GrantPrivilege.databaseAction( databaseAction, scope, grantees, qualifier)) |
group(keyword("GRANT") ~~ DatabaseAction ~~ Database ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((databaseAction, scope, grantees) => ast.GrantPrivilege.databaseAction( databaseAction, scope, grantees))
}
def DenyDatabasePrivilege: Rule1[ast.DenyPrivilege] = rule("DENY database privileges") {
group(keyword("DENY") ~~ QualifiedDatabaseAction ~~ Database ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((qualifier, databaseAction, scope, grantees) => ast.DenyPrivilege.databaseAction( databaseAction, scope, grantees, qualifier)) |
group(keyword("DENY") ~~ DatabaseAction ~~ Database ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((databaseAction, scope, grantees) => ast.DenyPrivilege.databaseAction( databaseAction, scope, grantees))
}
def RevokeDatabasePrivilege: Rule1[ast.RevokePrivilege] = rule("REVOKE database privileges") {
group(RevokeType ~~ QualifiedDatabaseAction ~~ Database ~~ keyword("FROM") ~~ SymbolicNameOrStringParameterList) ~~>>
((revokeType, qualifier, databaseAction, scope, grantees) => ast.RevokePrivilege.databaseAction(databaseAction, scope, grantees, revokeType, qualifier)) |
group(RevokeType ~~ DatabaseAction ~~ Database ~~ keyword("FROM") ~~ SymbolicNameOrStringParameterList) ~~>>
((revokeType, databaseAction, scope, grantees) => ast.RevokePrivilege.databaseAction(databaseAction, scope, grantees, revokeType))
}
//` ... ON GRAPH foo TO role`
def GrantGraphPrivilege: Rule1[ast.GrantPrivilege] = rule("GRANT graph privileges") {
group(keyword("GRANT") ~~ GraphAction ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((graphScope, action, qualifier, roles) => ast.GrantPrivilege.graphAction(action, None, graphScope, qualifier, roles)) |
group(keyword("GRANT") ~~ QualifiedGraphAction ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((graphScope, qualifier, action, roles) => ast.GrantPrivilege.graphAction(action, None, graphScope, qualifier, roles)) |
group(keyword("GRANT") ~~ GraphActionWithResource ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((resource, graphScope, action, roles) => ast.GrantPrivilege.graphAction(action, Some(resource), graphScope, List(ast.LabelAllQualifier()(InputPosition.NONE)), roles)) |
group(keyword("GRANT") ~~ QualifiedGraphActionWithResource ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((resource, graphScope, qualifier, action, roles) => ast.GrantPrivilege.graphAction(action, Some(resource), graphScope, qualifier, roles))
}
def DenyGraphPrivilege: Rule1[ast.DenyPrivilege] = rule("DENY graph privileges") {
group(keyword("DENY") ~~ GraphAction ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((graphScope, action, qualifier, roles) => ast.DenyPrivilege.graphAction(action, None, graphScope, qualifier, roles)) |
group(keyword("DENY") ~~ QualifiedGraphAction ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((graphScope, qualifier, action, roles) => ast.DenyPrivilege.graphAction(action, None, graphScope, qualifier, roles)) |
group(keyword("DENY") ~~ GraphActionWithResource ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((resource, graphScope, action, roles) => ast.DenyPrivilege.graphAction(action, Some(resource), graphScope, List(ast.LabelAllQualifier()(InputPosition.NONE)), roles)) |
group(keyword("DENY") ~~ QualifiedGraphActionWithResource ~~ keyword("TO") ~~ SymbolicNameOrStringParameterList) ~~>>
((resource, graphScope, qualifier, action, roles) => ast.DenyPrivilege.graphAction(action, Some(resource), graphScope, qualifier, roles))
}
def RevokeGraphPrivilege: Rule1[ast.RevokePrivilege] = rule("REVOKE graph privileges") {
group(RevokeType ~~ GraphAction ~~ keyword("FROM") ~~ SymbolicNameOrStringParameterList) ~~>>
((revokeType, graphScope, action, qualifier, roles) => ast.RevokePrivilege.graphAction(action, None, graphScope, qualifier, roles, revokeType)) |
group(RevokeType ~~ QualifiedGraphAction ~~ keyword("FROM") ~~ SymbolicNameOrStringParameterList) ~~>>
((revokeType, graphScope, qualifier, action, roles) => ast.RevokePrivilege.graphAction(action, None, graphScope, qualifier, roles, revokeType)) |
group(RevokeType ~~ GraphActionWithResource ~~ keyword("FROM") ~~ SymbolicNameOrStringParameterList) ~~>>
((revokeType, resource, graphScope, action, roles) => ast.RevokePrivilege.graphAction(action, Some(resource), graphScope, List(ast.LabelAllQualifier()(InputPosition.NONE)), roles, revokeType)) |
group(RevokeType ~~ QualifiedGraphActionWithResource ~~ keyword("FROM") ~~ SymbolicNameOrStringParameterList) ~~>>
((revokeType, resource, graphScope, qualifier, action, roles) => ast.RevokePrivilege.graphAction(action, Some(resource), graphScope, qualifier, roles, revokeType))
}
// Help methods for grant/deny/revoke
private def RevokeType: Rule1[ast.RevokeType] = rule("revoke type") {
keyword("REVOKE GRANT") ~~~> ast.RevokeGrantType() |
keyword("REVOKE DENY") ~~~> ast.RevokeDenyType() |
keyword("REVOKE") ~~~> ast.RevokeBothType()
}
// Dbms specific
private def DbmsAction: Rule1[ast.AdminAction] = rule("dbms action") {
keyword("CREATE ROLE") ~~~> (_ => ast.CreateRoleAction) |
keyword("DROP ROLE") ~~~> (_ => ast.DropRoleAction) |
keyword("ASSIGN ROLE") ~~~> (_ => ast.AssignRoleAction) |
keyword("REMOVE ROLE") ~~~> (_ => ast.RemoveRoleAction) |
keyword("SHOW ROLE") ~~~> (_ => ast.ShowRoleAction) |
keyword("ROLE MANAGEMENT") ~~~> (_ => ast.AllRoleActions) |
keyword("CREATE USER") ~~~> (_ => ast.CreateUserAction) |
keyword("DROP USER") ~~~> (_ => ast.DropUserAction) |
keyword("SHOW USER") ~~~> (_ => ast.ShowUserAction) |
keyword("SET USER STATUS") ~~~> (_ => ast.SetUserStatusAction) |
keyword("SET USER HOME DATABASE") ~~~> (_ => ast.SetUserHomeDatabaseAction) |
keyword("SET") ~~ PasswordKeyword ~~~> (_ => ast.SetPasswordsAction) |
keyword("ALTER USER") ~~~> (_ => ast.AlterUserAction) |
keyword("USER MANAGEMENT") ~~~> (_ => ast.AllUserActions) |
keyword("CREATE DATABASE") ~~~> (_ => ast.CreateDatabaseAction) |
keyword("DROP DATABASE") ~~~> (_ => ast.DropDatabaseAction) |
keyword("DATABASE MANAGEMENT") ~~~> (_ => ast.AllDatabaseManagementActions) |
keyword("SHOW PRIVILEGE") ~~~> (_ => ast.ShowPrivilegeAction) |
keyword("ASSIGN PRIVILEGE") ~~~> (_ => ast.AssignPrivilegeAction) |
keyword("REMOVE PRIVILEGE") ~~~> (_ => ast.RemovePrivilegeAction) |
keyword("PRIVILEGE MANAGEMENT") ~~~> (_ => ast.AllPrivilegeActions) |
group(keyword("ALL") ~~ optional(optional(keyword("DBMS")) ~~ keyword("PRIVILEGES")))~~~> (_ => ast.AllDbmsAction) |
group(keyword("EXECUTE") ~~ AdminKeyword ~~ keyword("PROCEDURES")) ~> (_ => ast.ExecuteAdminProcedureAction)
}
private def QualifiedDbmsAction: Rule2[List[ast.PrivilegeQualifier], ast.AdminAction] = rule("qualified dbms action") {
keyword("EXECUTE") ~~ Procedure ~> (_ => ast.ExecuteProcedureAction) |
keyword("EXECUTE BOOSTED") ~~ Procedure ~> (_ => ast.ExecuteBoostedProcedureAction) |
keyword("EXECUTE") ~~ Function ~> (_ => ast.ExecuteFunctionAction) |
keyword("EXECUTE BOOSTED") ~~ Function ~> (_ => ast.ExecuteBoostedFunctionAction)
}
private def Procedure: Rule1[List[ast.PrivilegeQualifier]] = ProcedureKeyword ~~ ProcedureIdentifier
private def ProcedureIdentifier: Rule1[List[ast.PrivilegeQualifier]] = rule("procedure identifier") {
oneOrMore(group(GlobbedNamespace ~ GlobbedProcedureName), separator = CommaSep) ~~>>
{ procedures => pos => procedures.map(p => ast.ProcedureQualifier(p._1, p._2)(pos)) }
}
private def Function: Rule1[List[ast.PrivilegeQualifier]] =
group(optional(keyword("USER") ~~ optional(keyword("DEFINED"))) ~~ FunctionKeyword) ~~ FunctionIdentifier
private def FunctionIdentifier: Rule1[List[ast.PrivilegeQualifier]] = rule("function identifier") {
oneOrMore(group(GlobbedNamespace ~ GlobbedFunctionName), separator = CommaSep) ~~>>
{ functions => pos => functions.map(p => ast.FunctionQualifier(p._1, p._2)(pos)) }
}
// Database specific
private def Database: Rule1[List[ast.DatabaseScope]] = rule("on a database") {
keyword("ON DEFAULT DATABASE") ~~~> (pos => List(ast.DefaultDatabaseScope()(pos))) |
keyword("ON HOME DATABASE") ~~~> (pos => List(ast.HomeDatabaseScope()(pos))) |
group(keyword("ON") ~~ DatabaseKeyword) ~~ group(
(SymbolicDatabaseNameOrStringParameterList ~~>> (params => pos => params.map(ast.NamedDatabaseScope(_)(pos)))) |
(keyword("*") ~~~> (pos => List(ast.AllDatabasesScope()(pos))))
)
}
private def DatabaseAction: Rule1[ast.DatabaseAction] = rule("database action") {
keyword("ACCESS") ~~~> (_ => ast.AccessDatabaseAction) |
keyword("START") ~~~> (_ => ast.StartDatabaseAction) |
keyword("STOP") ~~~> (_ => ast.StopDatabaseAction) |
group(keyword("CREATE") ~~ IndexKeyword) ~~~> (_ => ast.CreateIndexAction) |
group(keyword("DROP") ~~ IndexKeyword) ~~~> (_ => ast.DropIndexAction) |
group(keyword("SHOW") ~~ IndexKeyword) ~~~> (_ => ast.ShowIndexAction) |
group(IndexKeyword ~~ optional(keyword("MANAGEMENT"))) ~~~> (_ => ast.AllIndexActions) |
group(keyword("CREATE") ~~ ConstraintKeyword) ~~~> (_ => ast.CreateConstraintAction) |
group(keyword("DROP") ~~ ConstraintKeyword) ~~~> (_ => ast.DropConstraintAction) |
group(keyword("SHOW") ~~ ConstraintKeyword) ~~~> (_ => ast.ShowConstraintAction) |
group(ConstraintKeyword ~~ optional(keyword("MANAGEMENT"))) ~~~> (_ => ast.AllConstraintActions) |
group(keyword("CREATE NEW") ~~ optional(keyword("NODE")) ~~ LabelKeyword) ~~~> (_ => ast.CreateNodeLabelAction) |
group(keyword("CREATE NEW") ~~ optional(keyword("RELATIONSHIP")) ~~ TypeKeyword) ~~~> (_ => ast.CreateRelationshipTypeAction) |
group(keyword("CREATE NEW") ~~ optional(keyword("PROPERTY")) ~~ NameKeyword) ~~~> (_ => ast.CreatePropertyKeyAction) |
group(keyword("NAME") ~~ optional(keyword("MANAGEMENT"))) ~~~> (_ => ast.AllTokenActions) |
group(keyword("ALL") ~~ optional(optional(keyword("DATABASE")) ~~ keyword("PRIVILEGES"))) ~~~> (_ => ast.AllDatabaseAction)
}
private def QualifiedDatabaseAction: Rule2[List[ast.DatabasePrivilegeQualifier], ast.DatabaseAction] = rule("qualified database action") {
group(keyword("SHOW") ~~ TransactionKeyword ~~ UserQualifier ~> (_ => ast.ShowTransactionAction)) |
group(keyword("SHOW") ~~ TransactionKeyword ~> (_ => List(ast.UserAllQualifier()(InputPosition.NONE))) ~> (_ => ast.ShowTransactionAction)) |
group(keyword("TERMINATE") ~~ TransactionKeyword ~~ UserQualifier ~> (_ => ast.TerminateTransactionAction)) |
group(keyword("TERMINATE") ~~ TransactionKeyword ~> (_ => List(ast.UserAllQualifier()(InputPosition.NONE))) ~> (_ => ast.TerminateTransactionAction)) |
group(keyword("TRANSACTION") ~~ optional(keyword("MANAGEMENT")) ~~ UserQualifier ~> (_ => ast.AllTransactionActions)) |
group(keyword("TRANSACTION") ~~ optional(keyword("MANAGEMENT")) ~> (_ => List(ast.UserAllQualifier()(InputPosition.NONE))) ~> (_ => ast.AllTransactionActions))
}
private def UserQualifier: Rule1[List[ast.DatabasePrivilegeQualifier]] = rule("(usernameList)") {
group("(" ~~ SymbolicNameOrStringParameterList ~~ ")") ~~>> { userName => pos => userName.map(ast.UserQualifier(_)(pos)) } |
group("(" ~~ "*" ~~ ")") ~~~> { pos => List(ast.UserAllQualifier()(pos)) }
}
// Graph specific
private def Graph: Rule1[List[ast.GraphScope]] = rule("on a graph") {
keyword("ON DEFAULT GRAPH") ~~~> (pos => List(ast.DefaultGraphScope()(pos))) |
keyword("ON HOME GRAPH") ~~~> (pos => List(ast.HomeGraphScope()(pos))) |
group(keyword("ON") ~~ GraphKeyword) ~~ group(
(SymbolicDatabaseNameOrStringParameterList ~~>> (names => ipp => names.map(ast.NamedGraphScope(_)(ipp)))) |
keyword("*") ~~~> (ipp => List(ast.AllGraphsScope()(ipp)))
)
}
private def GraphAction: Rule3[List[ast.GraphScope], ast.GraphAction, List[ast.GraphPrivilegeQualifier]] = rule("graph action") {
group(keyword("ALL") ~~ optional(optional(keyword("GRAPH")) ~~ keyword("PRIVILEGES"))) ~~ Graph ~>
(_ => ast.AllGraphAction) ~> (_ => List(ast.AllQualifier()(InputPosition.NONE))) |
group(keyword("WRITE") ~~ Graph) ~> (_ => ast.WriteAction) ~> (_ => List(ast.ElementsAllQualifier()(InputPosition.NONE)))
}
private def QualifiedGraphAction: Rule3[List[ast.GraphScope], List[ast.GraphPrivilegeQualifier], ast.GraphAction] = rule("qualified graph action") {
group(keyword("CREATE") ~~ Graph ~~ ScopeQualifier ~> (_ => ast.CreateElementAction)) |
group(keyword("DELETE") ~~ Graph ~~ ScopeQualifier ~> (_ => ast.DeleteElementAction)) |
group(keyword("TRAVERSE") ~~ Graph ~~ ScopeQualifierWithProperty ~> (_ => ast.TraverseAction))
}
private def GraphActionWithResource: Rule3[ast.ActionResource, List[ast.GraphScope], ast.GraphAction] = rule("graph action with resource") {
group(keyword("SET LABEL") ~~ LabelResource ~~ Graph ~> (_ => ast.SetLabelAction)) |
group(keyword("REMOVE LABEL") ~~ LabelResource ~~ Graph ~> (_ => ast.RemoveLabelAction))
}
private def QualifiedGraphActionWithResource: Rule4[ast.ActionResource, List[ast.GraphScope], List[ast.GraphPrivilegeQualifier], ast.GraphAction] = rule("qualified graph action with resource") {
group(keyword("MERGE") ~~ PrivilegeProperty ~~ Graph ~~ ScopeQualifier ~> (_ => ast.MergeAdminAction)) |
group(keyword("SET PROPERTY") ~~ PrivilegeProperty ~~ Graph ~~ ScopeQualifier ~> (_ => ast.SetPropertyAction)) |
group(keyword("READ") ~~ PrivilegeProperty ~~ Graph ~~ ScopeQualifierWithProperty ~> (_ => ast.ReadAction)) |
group(keyword("MATCH") ~~ PrivilegeProperty ~~ Graph ~~ ScopeQualifierWithProperty ~> (_ => ast.MatchAction))
}
private def ScopeQualifier: Rule1[List[ast.GraphPrivilegeQualifier]] = rule("which element type and associated labels/relTypes qualifier combination") {
group(RelationshipKeyword ~~ SymbolicNamesList) ~~>> { relNames => pos => relNames.map(ast.RelationshipQualifier(_)(pos)) } |
group(RelationshipKeyword ~~ "*") ~~~> { pos => List(ast.RelationshipAllQualifier()(pos)) } |
group(NodeKeyword ~~ SymbolicNamesList) ~~>> { nodeName => pos => nodeName.map(ast.LabelQualifier(_)(pos)) } |
group(NodeKeyword ~~ "*") ~~~> { pos => List(ast.LabelAllQualifier()(pos)) } |
group(ElementKeyword ~~ SymbolicNamesList) ~~>> { elemName => pos => elemName.map(ast.ElementQualifier(_)(pos)) } |
optional(ElementKeyword ~~ "*") ~~~> { pos => List(ast.ElementsAllQualifier()(pos)) }
}
private def ScopeQualifierWithProperty: Rule1[List[ast.GraphPrivilegeQualifier]] = rule("which element type and associated labels/relTypes (props) qualifier combination") {
ScopeQualifier ~~ optional("(" ~~ "*" ~~ ")")
}
private def LabelResource: Rule1[ast.ActionResource] = rule("label used for set/remove label") {
group(SymbolicNamesList ~~>> {ast.LabelsResource(_)} |
group(keyword("*") ~~~> {ast.AllLabelResource()}))
}
private def PrivilegeProperty: Rule1[ast.ActionResource] = rule("{propertyList}") {
group("{" ~~ SymbolicNamesList ~~ "}") ~~>> {ast.PropertiesResource(_)} |
group("{" ~~ "*" ~~ "}") ~~~> {ast.AllPropertyResource()}
}
// Database management commands
def ShowDatabase: Rule1[ast.ShowDatabase] = rule("SHOW DATABASE") {
group(keyword("SHOW") ~~ ScopeForShowDatabase) ~~ optional(ShowCommandClauses) ~~>> (ast.ShowDatabase(_,_))
}
private def ScopeForShowDatabase: Rule1[ast.DatabaseScope] = rule("show database scope") {
group(keyword("DATABASE") ~~ SymbolicDatabaseNameOrStringParameter) ~~>> (ast.NamedDatabaseScope(_)) |
keyword("DATABASES") ~~~> ast.AllDatabasesScope() |
keyword("DEFAULT DATABASE") ~~~> ast.DefaultDatabaseScope() |
keyword("HOME DATABASE") ~~~> ast.HomeDatabaseScope()
}
def CreateDatabase: Rule1[ast.CreateDatabase] = rule("CREATE DATABASE") {
group(keyword("CREATE OR REPLACE DATABASE") ~~ SymbolicDatabaseNameOrStringParameter ~~ keyword("IF NOT EXISTS") ~~ WaitUntilComplete) ~~>> (ast.CreateDatabase(_, ast.IfExistsInvalidSyntax, _)) |
group(keyword("CREATE OR REPLACE DATABASE") ~~ SymbolicDatabaseNameOrStringParameter ~~ WaitUntilComplete) ~~>> (ast.CreateDatabase(_, ast.IfExistsReplace, _)) |
group(keyword("CREATE DATABASE") ~~ SymbolicDatabaseNameOrStringParameter ~~ keyword("IF NOT EXISTS") ~~ WaitUntilComplete) ~~>> (ast.CreateDatabase(_, ast.IfExistsDoNothing, _)) |
group(keyword("CREATE DATABASE") ~~ SymbolicDatabaseNameOrStringParameter ~~ WaitUntilComplete) ~~>> (ast.CreateDatabase(_, ast.IfExistsThrowError, _))
}
def DropDatabase: Rule1[ast.DropDatabase] = rule("DROP DATABASE") {
group(keyword("DROP DATABASE") ~~ SymbolicDatabaseNameOrStringParameter ~~ keyword("IF EXISTS") ~~ DataAction ~~ WaitUntilComplete) ~~>>
((dbName, dataAction, wait) => ast.DropDatabase(dbName, ifExists = true, dataAction, wait)) |
group(keyword("DROP DATABASE") ~~ SymbolicDatabaseNameOrStringParameter ~~ DataAction ~~ WaitUntilComplete) ~~>>
((dbName, dataAction, wait) => ast.DropDatabase(dbName, ifExists = false, dataAction, wait))
}
private def DataAction: Rule1[ast.DropDatabaseAdditionalAction] = rule("data action on drop database") {
keyword("DUMP DATA") ~~~> (_ => ast.DumpData) |
optional(keyword("DESTROY DATA")) ~~~> (_ => ast.DestroyData)
}
def StartDatabase: Rule1[ast.StartDatabase] = rule("START DATABASE") {
group(keyword("START DATABASE") ~~ SymbolicDatabaseNameOrStringParameter ~~ WaitUntilComplete) ~~>> (ast.StartDatabase(_, _))
}
def StopDatabase: Rule1[ast.StopDatabase] = rule("STOP DATABASE") {
group(keyword("STOP DATABASE") ~~ SymbolicDatabaseNameOrStringParameter ~~ WaitUntilComplete) ~~>> (ast.StopDatabase(_, _))
}
// Shared help methods
def SymbolicNameOrStringParameter: Rule1[Either[String, Parameter]] =
group(SymbolicNameString) ~~>> (s => _ => Left(s)) |
group(StringParameter) ~~>> (p => _ => Right(p))
def SymbolicDatabaseNameOrStringParameter: Rule1[Either[String, Parameter]] =
group(SymbolicDatabaseNameString) ~~>> (s => _ => Left(s)) |
group(StringParameter) ~~>> (p => _ => Right(p))
def SymbolicNameOrStringParameterList: Rule1[List[Either[String, Parameter]]] = rule("a list of symbolic names or string parameters") {
//noinspection LanguageFeature
(oneOrMore(WS ~~ SymbolicNameOrStringParameter ~~ WS, separator = ",") memoMismatches).suppressSubnodes
}
def SymbolicDatabaseNameOrStringParameterList: Rule1[List[Either[String, Parameter]]] = rule("a list of symbolic database names or string parameters") {
//noinspection LanguageFeature
(oneOrMore(WS ~~ SymbolicDatabaseNameOrStringParameter ~~ WS, separator = ",") memoMismatches).suppressSubnodes
}
private def WaitUntilComplete: Rule1[WaitUntilComplete] = rule("WAIT [n [SEC[OND[S]]]] | NOWAIT") {
group(keyword("WAIT") ~~ UnsignedIntegerLiteral ~~ optional(keyword("SEC") | keyword("SECOND") | keyword("SECONDS")) ~~>
(timeout => TimeoutAfter(timeout.value))) |
keyword("WAIT") ~> (_ => IndefiniteWait) |
optional(keyword("NOWAIT")) ~> (_ => NoWait)
}
// Keyword methods
private def RoleKeyword: Rule0 = keyword("ROLES") | keyword("ROLE")
private def UserKeyword: Rule0 = keyword("USERS") | keyword("USER")
private def PrivilegeKeyword: Rule0 = keyword("PRIVILEGES") | keyword("PRIVILEGE")
// Dbms specific
private def PasswordKeyword: Rule0 = keyword("PASSWORDS") | keyword("PASSWORD")
private def ProcedureKeyword: Rule0 = keyword("PROCEDURES") | keyword("PROCEDURE")
private def FunctionKeyword: Rule0 = keyword("FUNCTIONS") | keyword("FUNCTION")
private def AdminKeyword: Rule0 = keyword("ADMINISTRATOR") | keyword("ADMIN")
private def CommandKeyword: Rule0 = keyword("COMMANDS") | keyword("COMMAND")
// Database specific
private def DatabaseKeyword: Rule0 = keyword("DATABASES") | keyword("DATABASE")
private def LabelKeyword: Rule0 = keyword("LABELS") | keyword("LABEL")
private def TypeKeyword: Rule0 = keyword("TYPES") | keyword("TYPE")
private def NameKeyword: Rule0 = keyword("NAMES") | keyword("NAME")
private def TransactionKeyword: Rule0 = keyword("TRANSACTIONS") | keyword("TRANSACTION")
// Graph specific
private def GraphKeyword: Rule0 = keyword("GRAPHS") | keyword("GRAPH")
private def ElementKeyword: Rule0 = keyword("ELEMENTS") | keyword("ELEMENT")
private def RelationshipKeyword: Rule0 = keyword("RELATIONSHIPS") | keyword("RELATIONSHIP")
private def NodeKeyword: Rule0 = keyword("NODES") | keyword("NODE")
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy