From 34045efb38c15ef4ec3d84dbeebb694d78760d00 Mon Sep 17 00:00:00 2001 From: Khushboo Vashi Date: Wed, 20 Feb 2019 11:49:45 +0000 Subject: [PATCH] Modify the Download as CSV option to use the same connection as the Query Tool its running in so temporary tables etc. can be used. Fixes #3673 --- docs/en_US/release_notes_4_3.rst | 1 + .../datagrid/templates/datagrid/index.html | 1 - web/pgadmin/tools/sqleditor/__init__.py | 20 +----- .../tools/sqleditor/static/js/sqleditor.js | 65 +++++++++++++++++-- .../utils/driver/psycopg2/connection.py | 2 +- 5 files changed, 64 insertions(+), 25 deletions(-) diff --git a/docs/en_US/release_notes_4_3.rst b/docs/en_US/release_notes_4_3.rst index 2ad2e44b6..5ddd0e042 100644 --- a/docs/en_US/release_notes_4_3.rst +++ b/docs/en_US/release_notes_4_3.rst @@ -19,6 +19,7 @@ Bug fixes ********* | `Bug #3544 `_ - Make the Query Tool tab titles more concise and useful. +| `Bug #3673 `_ - Modify the Download as CSV option to use the same connection as the Query Tool its running in so temporary tables etc. can be used. | `Bug #3873 `_ - Fix context sub-menu alignment on Safari. | `Bug #3906 `_ - Fix alignment of Close and Maximize button of Grant Wizard. | `Bug #3912 `_ - Fix editing of table data with a JSON primary key. diff --git a/web/pgadmin/tools/datagrid/templates/datagrid/index.html b/web/pgadmin/tools/datagrid/templates/datagrid/index.html index 7f1c468ee..5dd0bdcd4 100644 --- a/web/pgadmin/tools/datagrid/templates/datagrid/index.html +++ b/web/pgadmin/tools/datagrid/templates/datagrid/index.html @@ -342,7 +342,6 @@ - {% endblock %} diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py index aa26e087a..51f812970 100644 --- a/web/pgadmin/tools/sqleditor/__init__.py +++ b/web/pgadmin/tools/sqleditor/__init__.py @@ -1393,29 +1393,16 @@ def save_file(): @login_required def start_query_download_tool(trans_id): sync_conn = None - (status, error_msg, conn, trans_obj, + (status, error_msg, sync_conn, trans_obj, session_obj) = check_transaction_status(trans_id) - if status and conn is not None and \ + if status and sync_conn is not None and \ trans_obj is not None and session_obj is not None: data = request.args if request.args else None try: if data and 'query' in data: sql = data['query'] - conn_id = str(random.randint(1, 9999999)) - sync_conn = conn.manager.connection( - did=trans_obj.did, - conn_id=conn_id, - auto_reconnect=False, - async_=False - ) - - sync_conn.connect(autocommit=False) - - def cleanup(): - conn.manager.connections[sync_conn.conn_id]._release() - del conn.manager.connections[sync_conn.conn_id] # This returns generator of records. status, gen = sync_conn.execute_on_server_as_csv( @@ -1427,7 +1414,6 @@ def start_query_download_tool(trans_id): r.headers[ "Content-Disposition" ] = "attachment;filename=error.csv" - r.call_on_close(cleanup) return r r = Response( @@ -1459,13 +1445,11 @@ def start_query_download_tool(trans_id): "Content-Disposition" ] = "attachment;filename={0}".format(filename) - r.call_on_close(cleanup) return r except Exception as e: r = Response('"{0}"'.format(e), mimetype='text/csv') r.headers["Content-Disposition"] = "attachment;filename=error.csv" - r.call_on_close(cleanup) return r else: return internal_server_error( diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js index 65ea1629b..75896061c 100644 --- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js +++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js @@ -307,12 +307,12 @@ define('tools.querytool', [ geometry_viewer.load(main_docker); // Add all the panels to the docker - self.data_output_panel = main_docker.addPanel('data_output', wcDocker.DOCK.BOTTOM, sql_panel_obj); + self.scratch_panel = main_docker.addPanel('scratch', wcDocker.DOCK.RIGHT, sql_panel_obj); + self.history_panel = main_docker.addPanel('history', wcDocker.DOCK.STACKED, sql_panel_obj); + self.data_output_panel = main_docker.addPanel('data_output', wcDocker.DOCK.BOTTOM); self.explain_panel = main_docker.addPanel('explain', wcDocker.DOCK.STACKED, self.data_output_panel); self.messages_panel = main_docker.addPanel('messages', wcDocker.DOCK.STACKED, self.data_output_panel); self.notifications_panel = main_docker.addPanel('notifications', wcDocker.DOCK.STACKED, self.data_output_panel); - self.history_panel = main_docker.addPanel('history', wcDocker.DOCK.STACKED, sql_panel_obj); - self.scratch_panel = main_docker.addPanel('scratch', wcDocker.DOCK.RIGHT, sql_panel_obj); self.render_history_grid(); queryToolNotifications.renderNotificationsGrid(self.notifications_panel); @@ -3502,6 +3502,12 @@ define('tools.querytool', [ } self.disable_tool_buttons(false); is_query_running = false; + if(!_.isUndefined(self.download_csv_obj)) { + self.download_csv_obj.abort(); + $('#btn-flash').prop('disabled', false); + self.trigger( + 'pgadmin-sqleditor:loading-icon:hide'); + } setTimeout(() => { self.gridView.query_tool_obj.focus(); }, 200); }) .fail(function(e) { @@ -3517,7 +3523,6 @@ define('tools.querytool', [ // Trigger query result download to csv. trigger_csv_download: function(query, filename) { var self = this, - link = $(this.container).find('#download-csv'), url = url_for('sqleditor.query_tool_download', { 'trans_id': self.transId, }); @@ -3526,7 +3531,57 @@ define('tools.querytool', [ query: query, filename: filename, }); - link.attr('src', url); + + // Get the CSV file + self.download_csv_obj = $.ajax({ + type: 'GET', + url: url, + cache: false, + async: true, + xhrFields: { + responseType: 'blob', + }, + beforeSend: function() { + // Disable the Execute button + $('#btn-flash').prop('disabled', true); + self.disable_tool_buttons(true); + + self.trigger( + 'pgadmin-sqleditor:loading-icon:show', + gettext('Downloading CSV...') + ); + }, + }) + .done(function(response) { + let urlCreator = window.URL || window.webkitURL, + url = urlCreator.createObjectURL(response), + link = document.createElement('a'); + + link.setAttribute('href', url); + link.setAttribute('download', filename); + link.click(); + + self.download_csv_obj = undefined; + // Enable the execute button + $('#btn-flash').prop('disabled', false); + self.disable_tool_buttons(false); + self.trigger( + 'pgadmin-sqleditor:loading-icon:hide'); + + }) + .fail(function(err) { + let msg = ''; + + if (err.statusText == 'abort') { + msg = gettext('CSV Download cancelled.'); + } else { + msg = httpErrorHandler.handleQueryToolAjaxError( + pgAdmin, self, err, gettext('Download CSV'), [], true + ); + } + alertify.alert(gettext('Download CSV error'), msg); + }); + }, call_cache_preferences: function() { diff --git a/web/pgadmin/utils/driver/psycopg2/connection.py b/web/pgadmin/utils/driver/psycopg2/connection.py index bbbf0bc76..012266d2f 100644 --- a/web/pgadmin/utils/driver/psycopg2/connection.py +++ b/web/pgadmin/utils/driver/psycopg2/connection.py @@ -673,7 +673,7 @@ WHERE Returns: Generator response """ - status, cur = self.__cursor(server_cursor=True) + status, cur = self.__cursor() self.row_count = 0 if not status: