(cqlsh) tab completion for triggers

patch by Mikhail Stepura; reviewed by Tyler Hobbs for CASSANDRA-7824
This commit is contained in:
Mikhail Stepura 2014-08-28 16:10:36 -07:00
parent bbbdec63a4
commit 1456ec8318
4 changed files with 66 additions and 0 deletions

View File

@ -1,4 +1,5 @@
2.1.1
* (cqlsh) tab-completion for triggers (CASSANDRA-7824)
* (cqlsh): Support for query paging (CASSANDRA-7514)
* (cqlsh): Show progress of COPY operations (CASSANDRA-7789)
* Add syntax to remove multiple elements from a map (CASSANDRA-6599)

View File

@ -711,6 +711,14 @@ class Shell(cmd.Cmd):
return cql3handling.UserTypesMeta.from_layout(data)
def get_trigger_names(self, ksname=None):
if ksname is None:
ksname = self.current_keyspace
return [trigger.name
for table in self.get_keyspace_meta(ksname).tables.values()
for trigger in table.triggers.values()]
def reset_statement(self):
self.reset_prompt()
self.statement.truncate(0)

View File

@ -540,6 +540,39 @@ The @DROP TYPE@ statement results in the immediate, irreversible removal of a ty
If the type does not exist, an error will be returned unless @IF EXISTS@ is used, in which case the operation is a no-op.
h3(#createTriggerStmt). CREATE TRIGGER
__Syntax:__
bc(syntax)..
<create-trigger-stmt> ::= CREATE TRIGGER ( IF NOT EXISTS )? ( <triggername> )?
ON <tablename>
USING <string>
p.
__Sample:__
bc(sample).
CREATE TRIGGER myTrigger ON myTable USING 'org.apache.cassandra.triggers.InvertedIndex';
The actual logic that makes up the trigger can be written in any Java (JVM) language and exists outside the database. You place the trigger code in a @lib/triggers@ subdirectory of the Cassandra installation directory, it loads during cluster startup, and exists on every node that participates in a cluster. The trigger defined on a table fires before a requested DML statement occurs, which ensures the atomicity of the transaction.
h3(#dropTriggerStmt). DROP TRIGGER
__Syntax:__
bc(syntax)..
<drop-trigger-stmt> ::= DROP TRIGGER ( IF EXISTS )? ( <triggername> )?
ON <tablename>
p.
__Sample:__
bc(sample).
DROP TRIGGER myTrigger ON myTable;
@DROP TRIGGER@ statement removes the registration of a trigger created using @CREATE TRIGGER@.
h2(#dataManipulation). Data Manipulation
h3(#insertStmt). INSERT

View File

@ -228,10 +228,12 @@ JUNK ::= /([ \t\r\f\v]+|(--|[/][/])[^\n\r]*([\n\r]|$)|[/][*].*?[*][/])/ ;
| <createColumnFamilyStatement>
| <createIndexStatement>
| <createUserTypeStatement>
| <createTriggerStatement>
| <dropKeyspaceStatement>
| <dropColumnFamilyStatement>
| <dropIndexStatement>
| <dropUserTypeStatement>
| <dropTriggerStatement>
| <alterTableStatement>
| <alterKeyspaceStatement>
| <alterUserTypeStatement>
@ -1153,6 +1155,28 @@ def username_name_completer(ctxt, cass):
session = cass.session
return [maybe_quote(row.values()[0].replace("'", "''")) for row in session.execute("LIST USERS")]
syntax_rules += r'''
<createTriggerStatement> ::= "CREATE" "TRIGGER" ( "IF" "NOT" "EXISTS" )? <cident>
"ON" cf=<columnFamilyName> "USING" class=<stringLiteral>
;
<dropTriggerStatement> ::= "DROP" "TRIGGER" ( "IF" "EXISTS" )? triggername=<cident>
"ON" cf=<columnFamilyName>
;
'''
explain_completion('createTriggerStatement', 'class', '\'fully qualified class name\'')
def get_trigger_names(ctxt, cass):
ks = ctxt.get_binding('ksname', None)
if ks is not None:
ks = dequote_name(ks)
return cass.get_trigger_names(ks)
@completer_for('dropTriggerStatement', 'triggername')
def alter_type_field_completer(ctxt, cass):
names = get_trigger_names(ctxt, cass)
return map(maybe_escape_name, names)
# END SYNTAX/COMPLETION RULE DEFINITIONS
CqlRuleSet.append_rules(syntax_rules)