瀏覽代碼

HUE-2963 [beeswax] Allow the user to be able to clear the recent queries table

Romain Rigaux 10 年之前
父節點
當前提交
2cc394e

+ 14 - 1
apps/beeswax/src/beeswax/api.py

@@ -39,12 +39,13 @@ from beeswax.data_export import upload
 from beeswax.design import HQLdesign
 from beeswax.conf import USE_GET_LOG_API
 from beeswax.forms import QueryForm
+from beeswax.models import Session, QueryHistory
 from beeswax.server import dbms
 from beeswax.server.dbms import expand_exception, get_query_server_config, QueryServerException, QueryServerTimeoutException
 from beeswax.views import authorized_get_design, authorized_get_query_history, make_parameterization_form,\
                           safe_get_design, save_design, massage_columns_for_json, _get_query_handle_and_state, \
                           _parse_out_hadoop_jobs
-from beeswax.models import Session
+
 
 LOG = logging.getLogger(__name__)
 
@@ -637,6 +638,18 @@ def query_history_to_dict(request, query_history):
   return query_history_dict
 
 
+def clear_history(request):
+  response = {'status': -1, 'message': ''}
+
+  if request.method != 'POST':
+    response['message'] = _('A POST request is required.')
+  else:
+    response['count'] = QueryHistory.objects.filter(owner=request.user, is_cleared=False).update(is_cleared=True)
+    response['status'] = 0
+
+  return JsonResponse(response)
+
+
 # Proxy API for Metastore App
 def describe_table(request, database, table):
   try:

+ 116 - 0
apps/beeswax/src/beeswax/migrations/0014_auto__add_field_queryhistory_is_cleared.py

@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'QueryHistory.is_cleared'
+        db.add_column(u'beeswax_queryhistory', 'is_cleared',
+                      self.gf('django.db.models.fields.BooleanField')(default=False),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'QueryHistory.is_cleared'
+        db.delete_column(u'beeswax_queryhistory', 'is_cleared')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'beeswax.metainstall': {
+            'Meta': {'object_name': 'MetaInstall'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'installed_example': ('django.db.models.fields.BooleanField', [], {})
+        },
+        u'beeswax.queryhistory': {
+            'Meta': {'ordering': "['-submission_date']", 'object_name': 'QueryHistory'},
+            'design': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['beeswax.SavedQuery']", 'null': 'True'}),
+            'extra': ('django.db.models.fields.TextField', [], {'default': "'{}'"}),
+            'has_results': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_cleared': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_redacted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_state': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'log_context': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True'}),
+            'modified_row_count': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
+            'notify': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'operation_type': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'query': ('django.db.models.fields.TextField', [], {}),
+            'query_type': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+            'server_guid': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '1024', 'null': 'True'}),
+            'server_host': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128'}),
+            'server_id': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True'}),
+            'server_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128'}),
+            'server_port': ('django.db.models.fields.PositiveIntegerField', [], {'default': '10000'}),
+            'server_type': ('django.db.models.fields.CharField', [], {'default': "'beeswax'", 'max_length': '128'}),
+            'statement_number': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+            'submission_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
+        },
+        u'beeswax.savedquery': {
+            'Meta': {'ordering': "['-mtime']", 'object_name': 'SavedQuery'},
+            'data': ('django.db.models.fields.TextField', [], {'max_length': '65536'}),
+            'desc': ('django.db.models.fields.TextField', [], {'max_length': '1024'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_auto': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
+            'is_redacted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
+            'mtime': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'type': ('django.db.models.fields.IntegerField', [], {})
+        },
+        u'beeswax.session': {
+            'Meta': {'object_name': 'Session'},
+            'application': ('django.db.models.fields.CharField', [], {'default': "'beeswax'", 'max_length': '128'}),
+            'guid': ('django.db.models.fields.TextField', [], {'max_length': "'100'"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_used': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'properties': ('django.db.models.fields.TextField', [], {'default': "'{}'"}),
+            'secret': ('django.db.models.fields.TextField', [], {'max_length': "'100'"}),
+            'server_protocol_version': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+            'status_code': ('django.db.models.fields.PositiveSmallIntegerField', [], {})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        }
+    }
+
+    complete_apps = ['beeswax']

+ 1 - 0
apps/beeswax/src/beeswax/models.py

@@ -84,6 +84,7 @@ class QueryHistory(models.Model):
 
   is_redacted = models.BooleanField(default=False)
   extra = models.TextField(default='{}')                   # Json fields for extra properties
+  is_cleared = models.BooleanField(default=False)
 
   class Meta:
     ordering = ['-submission_date']

+ 13 - 0
apps/beeswax/src/beeswax/static/beeswax/js/beeswax.vm.js

@@ -417,6 +417,19 @@ function BeeswaxViewModel(server, assistHelper) {
     $.ajax(request);
   };
 
+  self.clearQueryHistory = function() {
+    var request = {
+      url: '/' + self.server() + '/api/query/clear_history/',
+      dataType: 'json',
+      type: 'POST',
+      success: function(data) {
+        $(document).trigger('clear.history', [data]);
+      },
+      error: error_fn,
+      cache: false
+    };
+    $.ajax(request);
+  };
 
   self.fetchParameters = function() {
     $(document).trigger('fetch.parameters');

+ 6 - 1
apps/beeswax/src/beeswax/templates/execute.mako

@@ -352,6 +352,7 @@ ${ layout.menubar(section='query') }
               <!--[if !IE]><!--><i class="fa fa-spinner fa-spin" style="font-size: 20px; color: #DDD"></i><!--<![endif]-->
               <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }"/><![endif]-->
             </div>
+            <i class="fa fa-times" data-bind="click: $root.clearQueryHistory"></i>
             <table id="recentQueries" class="table table-striped table-condensed datatables" cellpadding="0" cellspacing="0" data-tablescroller-enforce-height="true">
               <thead>
                 <tr>
@@ -1241,7 +1242,7 @@ $(document).ready(function () {
     recentQueries.fnClearTable();
     var locale = window.navigator.userLanguage || window.navigator.language;
     moment.locale(locale);
-    $.getJSON("${ url(app_name + ':list_query_history') }?format=json", function(data) {
+    $.getJSON("${ url(app_name + ':list_query_history') }?format=json&recent=true", function(data) {
       if (data && data.queries) {
         var _rows = [];
         $(data.queries).each(function(cnt, item){
@@ -1326,6 +1327,10 @@ $(document).ready(function () {
     $("#columnAnalysis").hide();
   });
 
+  $(document).on("clear.history", function() {
+    recentQueries.fnClearTable();
+  });
+
   $(document).on("shown", "a[data-toggle='tab']:not(.sidetab)", function (e) {
     if ($(e.target).attr("href") == "#log") {
       logsAtEnd = true;

+ 2 - 0
apps/beeswax/src/beeswax/urls.py

@@ -82,6 +82,8 @@ urlpatterns += patterns(
   url(r'^api/query/(?P<query_history_id>\d+)/results/save/hdfs/directory$', 'save_results_hdfs_directory', name='api_save_results_hdfs_directory'),
   url(r'^api/watch/json/(?P<id>\d+)$', 'watch_query_refresh_json', name='api_watch_query_refresh_json'),
 
+  url(r'^api/query/clear_history/$', 'clear_history', name='clear_history'),
+
   url(r'^api/table/(?P<database>\w+)/(?P<table>\w+)$', 'describe_table', name='describe_table'),
   url(r'^api/analyze/(?P<database>\w+)/(?P<table>\w+)/(?P<columns>\w+)?$', 'analyze_table', name='analyze_table'),
   url(r'^api/table/(?P<database>\w+)/(?P<table>\w+)/stats/(?P<column>\w+)?$', 'get_table_stats', name='get_table_stats'),

+ 5 - 0
apps/beeswax/src/beeswax/views.py

@@ -940,6 +940,11 @@ def _list_query_history(user, querydict, page_size, prefix=""):
     else:
       db_queryset = db_queryset.filter(design__type=SavedQuery.TYPES_MAPPING[d_type])
 
+  # If recent query
+  recent = querydict.get('recent')
+  if recent:
+    db_queryset = db_queryset.filter(is_cleared=False)
+
   # Ordering
   sort_key = querydict.get(prefix + 'sort')
   if sort_key: