cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mish...@apache.org
Subject [1/3] git commit: (cqlsh): Support for query paging
Date Mon, 08 Sep 2014 03:10:12 GMT
Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.1 a44d641e8 -> f1f5f5fd3
  refs/heads/trunk f203f0f3f -> f34e829a2


(cqlsh): Support for query paging

patch by Mikhail Stepura; reviewed by Aleksey Yeschenko for CASSANDRA-7514


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f1f5f5fd
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f1f5f5fd
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f1f5f5fd

Branch: refs/heads/cassandra-2.1
Commit: f1f5f5fd3ac9bcf20fd68bae2f639ab12e2c360d
Parents: a44d641
Author: Mikhail Stepura <mishail@apache.org>
Authored: Fri Aug 29 13:13:16 2014 -0700
Committer: Mikhail Stepura <mishail@apache.org>
Committed: Sun Sep 7 20:09:14 2014 -0700

----------------------------------------------------------------------
 CHANGES.txt                                  |   1 +
 bin/cqlsh                                    | 165 +++++++++++++---------
 pylib/cqlshlib/test/test_cqlsh_completion.py |   2 +-
 3 files changed, 97 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f1f5f5fd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 18d6872..7737269 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.1.1
+ * (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)
  * Support non-equals conditions in lightweight transactions (CASSANDRA-6839)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f1f5f5fd/bin/cqlsh
----------------------------------------------------------------------
diff --git a/bin/cqlsh b/bin/cqlsh
index dfce885..d61a008 100755
--- a/bin/cqlsh
+++ b/bin/cqlsh
@@ -105,7 +105,7 @@ except ImportError, e:
              'Module load path: %r\n\n'
              'Error: %s\n' % (sys.executable, sys.path, e))
 
-from cassandra.cluster import Cluster
+from cassandra.cluster import Cluster, PagedResult
 from cassandra.query import SimpleStatement, ordered_dict_factory
 from cassandra.policies import WhiteListRoundRobinPolicy
 from cassandra.metadata import protect_name, protect_names, protect_value
@@ -147,7 +147,6 @@ DEFAULT_PROTOCOL_VERSION = 3
 
 DEFAULT_TIME_FORMAT = '%Y-%m-%d %H:%M:%S%z'
 DEFAULT_FLOAT_PRECISION = 5
-DEFAULT_SELECT_LIMIT = 10000
 DEFAULT_MAX_TRACE_WAIT = 10
 
 if readline is not None and readline.__doc__ is not None and 'libedit' in readline.__doc__:
@@ -204,6 +203,7 @@ my_commands_ending_with_newline = (
     'debug',
     'tracing',
     'expand',
+    'paging',
     'exit',
     'quit'
 )
@@ -231,6 +231,7 @@ cqlsh_extra_syntax_rules = r'''
                    | <tracingCommand>
                    | <expandCommand>
                    | <exitCommand>
+                   | <pagingCommand>
                    ;
 
 <describeCommand> ::= ( "DESCRIBE" | "DESC" )
@@ -294,6 +295,9 @@ cqlsh_extra_syntax_rules = r'''
 <expandCommand> ::= "EXPAND" ( switch=( "ON" | "OFF" ) )?
                    ;
 
+<pagingCommand> ::= "PAGING" ( switch=( "ON" | "OFF" ) )?
+                  ;
+
 <exitCommand> ::= "exit" | "quit"
                 ;
 
@@ -481,8 +485,10 @@ class Shell(cmd.Cmd):
     stop = False
     last_hist = None
     shunted_query_out = None
+    use_paging = True
     csv_dialect_defaults = dict(delimiter=',', doublequote=False,
                                 escapechar='\\', quotechar='"')
+    default_page_size = 100
 
     def __init__(self, hostname, port, color=False,
                  username=None, password=None, encoding=None, stdin=None, tty=True,
@@ -899,16 +905,12 @@ class Shell(cmd.Cmd):
         stop_tracing = ksname == 'system_traces' or (ksname is None and self.current_keyspace
== 'system_traces')
         self.tracing_enabled = self.tracing_enabled and not stop_tracing
         statement = parsed.extract_orig()
-        with_default_limit = parsed.get_binding('limit') is None
-        if with_default_limit:
-            statement = "%s LIMIT %d;" % (statement[:-1], DEFAULT_SELECT_LIMIT)
-        self.perform_statement(statement, with_default_limit=with_default_limit)
+        self.perform_statement(statement)
         self.tracing_enabled = tracing_was_enabled
 
-    def perform_statement(self, statement, with_default_limit=False):
-        stmt = SimpleStatement(statement, consistency_level=self.consistency_level)
-        result = self.perform_simple_statement(stmt,
-                                                with_default_limit=with_default_limit)
+    def perform_statement(self, statement):
+        stmt = SimpleStatement(statement, consistency_level=self.consistency_level, fetch_size=self.default_page_size
if self.use_paging else None)
+        result = self.perform_simple_statement(stmt)
         if self.tracing_enabled:
             if stmt.trace:
                 print_trace(self, stmt.trace)
@@ -924,7 +926,7 @@ class Shell(cmd.Cmd):
         cf = self.cql_unprotect_name(parsed.get_binding('cfname'))
         return self.get_table_meta(ks, cf)
 
-    def perform_simple_statement(self, statement, with_default_limit=False):
+    def perform_simple_statement(self, statement):
         if not statement:
             return False
         rows = None
@@ -941,7 +943,7 @@ class Shell(cmd.Cmd):
                 return False
 
         if statement.query_string[:6].lower() == 'select' or statement.query_string.lower().startswith("list"):
-            self.print_result(rows, with_default_limit, self.parse_for_table_meta(statement.query_string))
+            self.print_result(rows, self.parse_for_table_meta(statement.query_string))
         elif rows:
             # CAS INSERT/UPDATE
             self.writeresult("")
@@ -949,14 +951,33 @@ class Shell(cmd.Cmd):
         self.flush_output()
         return True
 
-    def print_result(self, rows, with_default_limit, table_meta):
+    def print_result(self, rows, table_meta):
         self.decoding_errors = []
 
         self.writeresult("")
-        if rows:
-            rows = list(rows)  # this may be an iterator if the result is large enough to
page
-        self.print_static_result(rows, table_meta)
-        self.writeresult("(%d rows)" % len(rows or []))
+        if isinstance(rows, PagedResult) and self.tty:
+            num_rows = 0
+            while True:
+                page = list(rows.current_response)
+                if not page:
+                    break
+                num_rows += len(page)
+                self.print_static_result(page, table_meta)
+                if not rows.response_future.has_more_pages:
+                    break
+                raw_input("---MORE---")
+
+                rows.response_future.start_fetching_next_page()
+                result = rows.response_future.result()
+                if rows.response_future.has_more_pages:
+                    rows.current_response = result.current_response
+                else:
+                    rows.current_response = iter(result)
+        else:
+            rows = list(rows or [])
+            num_rows = len(rows)
+            self.print_static_result(rows, table_meta)
+        self.writeresult("(%d rows)" % num_rows)
 
         if self.decoding_errors:
             for err in self.decoding_errors[:2]:
@@ -965,13 +986,6 @@ class Shell(cmd.Cmd):
                 self.writeresult('%d more decoding errors suppressed.'
                                  % (len(self.decoding_errors) - 2), color=RED)
 
-        if with_default_limit:
-            if len(rows) == DEFAULT_SELECT_LIMIT:
-                self.writeresult("Default LIMIT of %d was used. "
-                                 "Specify your own LIMIT clause to get more results."
-                                 % DEFAULT_SELECT_LIMIT, color=RED)
-                self.writeresult("")
-
     def print_static_result(self, rows, table_meta):
         if not rows:
             # print header only
@@ -1613,29 +1627,7 @@ class Shell(cmd.Cmd):
 
           TRACING with no arguments shows the current tracing status.
         """
-        switch = parsed.get_binding('switch')
-        if switch is None:
-            if self.tracing_enabled:
-                print "Tracing is currently enabled. Use TRACING OFF to disable"
-            else:
-                print "Tracing is currently disabled. Use TRACING ON to enable."
-            return
-
-        if switch.upper() == 'ON':
-            if self.tracing_enabled:
-                self.printerr('Tracing is already enabled. '
-                              'Use TRACING OFF to disable.')
-                return
-            self.tracing_enabled = True
-            print 'Now tracing requests.'
-            return
-
-        if switch.upper() == 'OFF':
-            if not self.tracing_enabled:
-                self.printerr('Tracing is not enabled.')
-                return
-            self.tracing_enabled = False
-            print 'Disabled tracing.'
+        self.tracing_enabled = SwitchCommand("TRACING", "Tracing").execute(self.tracing_enabled,
parsed, self.printerr)
 
     def do_expand(self, parsed):
         """
@@ -1655,29 +1647,7 @@ class Shell(cmd.Cmd):
 
           EXPAND with no arguments shows the current value of expand setting.
         """
-        switch = parsed.get_binding('switch')
-        if switch is None:
-            if self.expand_enabled:
-                print "Expanded output is currently enabled. Use EXPAND OFF to disable"
-            else:
-                print "Expanded output is currently disabled. Use EXPAND ON to enable."
-            return
-
-        if switch.upper() == 'ON':
-            if self.expand_enabled:
-                self.printerr('Expanded output is already enabled. '
-                              'Use EXPAND OFF to disable.')
-                return
-            self.expand_enabled = True
-            print 'Now printing expanded output'
-            return
-
-        if switch.upper() == 'OFF':
-            if not self.expand_enabled:
-                self.printerr('Expanded output is not enabled.')
-                return
-            self.expand_enabled = False
-            print 'Disabled expanded output.'
+        self.expand_enabled = SwitchCommand("EXPAND", "Expanded output").execute(self.expand_enabled,
parsed, self.printerr)
 
     def do_consistency(self, parsed):
         """
@@ -1753,6 +1723,26 @@ class Shell(cmd.Cmd):
             else:
                 self.printerr("*** No help on %s" % (t,))
 
+    def do_paging(self, parsed):
+        """
+        PAGING [cqlsh]
+
+          Enables or disables query paging.
+
+        PAGING ON
+
+          Enables query paging for all further queries.
+
+        PAGING OFF
+
+          Disables paging.
+
+        PAGING
+
+          PAGING with no arguments shows the current query paging status.
+        """
+        self.use_paging = SwitchCommand("PAGING", "Query paging").execute(self.use_paging,
parsed, self.printerr)
+
     def applycolor(self, text, color=None):
         if not color or not self.color:
             return text
@@ -1775,6 +1765,41 @@ class Shell(cmd.Cmd):
         self.writeresult(text, color, newline=newline, out=sys.stderr)
 
 
+class SwitchCommand(object):
+    command = None
+    description = None
+
+    def __init__(self, command, desc):
+        self.command = command
+        self.description = desc
+
+    def execute(self, state, parsed, printerr):
+        switch = parsed.get_binding('switch')
+        if switch is None:
+            if state:
+                print "%s is currently enabled. Use %s OFF to disable" \
+                      % (self.description, self.command)
+            else:
+                print "%s is currently disabled. Use %s ON to enable." \
+                      % (self.description, self.command)
+            return state
+
+        if switch.upper() == 'ON':
+            if state:
+                printerr('%s is already enabled. Use %s OFF to disable.'
+                         % (self.description, self.command))
+                return state
+            print 'Now %s is enabled' % (self.description,)
+            return True
+
+        if switch.upper() == 'OFF':
+            if not state:
+                printerr('%s is not enabled.' % (self.description,))
+                return state
+            print 'Disabled %s.' % (self.description,)
+            return False
+
+
 def option_with_default(cparser_getter, section, option, default=None):
     try:
         return cparser_getter(section, option)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f1f5f5fd/pylib/cqlshlib/test/test_cqlsh_completion.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_cqlsh_completion.py b/pylib/cqlshlib/test/test_cqlsh_completion.py
index 8d3b7c4..820414d 100644
--- a/pylib/cqlshlib/test/test_cqlsh_completion.py
+++ b/pylib/cqlshlib/test/test_cqlsh_completion.py
@@ -98,7 +98,7 @@ class TestCqlshCompletion(CqlshCompletionCase):
     def test_complete_on_empty_string(self):
         self.trycompletions('', choices=('?', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY',
                                          'COPY', 'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE',
-                                         'DROP', 'GRANT', 'HELP', 'INSERT', 'LIST', 'REVOKE',
+                                         'DROP', 'GRANT', 'HELP', 'INSERT', 'LIST', 'PAGING',
'REVOKE',
                                          'SELECT', 'SHOW', 'SOURCE', 'TRACING', 'EXPAND',
'TRUNCATE',
                                          'UPDATE', 'USE', 'exit', 'quit'))
 


Mime
View raw message