mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-10 23:45:58 -06:00
Load, and save the files in the Query Editor.
Also, the changes done by Ashesh to resolved few issue with the file manager in 'Select' mode.
This commit is contained in:
parent
4dc7f84761
commit
1aeab98a2b
File diff suppressed because it is too large
Load Diff
@ -1156,3 +1156,12 @@ form[name="change_password_form"] .help-block {
|
||||
height: 32px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
/* Overriding the css for the dropzone */
|
||||
.dropzone .dz-preview .dz-progress {
|
||||
height: initial;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-progress .dz-upload {
|
||||
bottom: initial;
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ body {
|
||||
<div class="sql-editor" data-trans-id="{{ uniqueId }}">
|
||||
<div id="btn-toolbar" class="pg-prop-btn-group" role="toolbar" aria-label="">
|
||||
<div class="btn-group" role="group" aria-label="">
|
||||
<button id="btn-load-file" type="button" class="btn btn-default btn-load-file" title="{{ _('Open File') }}">
|
||||
<i class="fa fa-folder-open-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button id="btn-save" type="button" class="btn btn-default" title="{{ _('Save') }}" disabled>
|
||||
<i class="fa fa-floppy-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
@ -13,6 +13,7 @@ MODULE_NAME = 'sqleditor'
|
||||
import json
|
||||
import pickle
|
||||
import random
|
||||
import os
|
||||
from flask import Response, url_for, render_template, session, request
|
||||
from flask.ext.babel import gettext
|
||||
from flask.ext.security import login_required
|
||||
@ -21,7 +22,13 @@ from pgadmin.utils.ajax import make_json_response, bad_request, success_return,
|
||||
from pgadmin.utils.driver import get_driver
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
from pgadmin.tools.sqleditor.command import QueryToolCommand
|
||||
from pgadmin.utils import get_storage_directory
|
||||
|
||||
# import unquote from urlib for python2.x and python3.x
|
||||
try:
|
||||
from urllib import unquote
|
||||
except Exception as e:
|
||||
from urllib.parse import unquote
|
||||
|
||||
# Async Constants
|
||||
ASYNC_OK = 1
|
||||
@ -44,7 +51,7 @@ class SqlEditorModule(PgAdminModule):
|
||||
A module class for SQL Grid derived from PgAdminModule.
|
||||
"""
|
||||
|
||||
LABEL = "SQL Editor"
|
||||
LABEL = gettext("SQL Editor")
|
||||
|
||||
def get_own_menuitems(self):
|
||||
return {}
|
||||
@ -949,3 +956,87 @@ def is_begin_required(query):
|
||||
return True
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@blueprint.route('/load_file/', methods=["PUT", "POST"])
|
||||
@login_required
|
||||
def load_file():
|
||||
"""
|
||||
This function gets name of file from request data
|
||||
reads the data and sends back in reponse
|
||||
"""
|
||||
if request.data:
|
||||
file_data = json.loads(request.data.decode())
|
||||
|
||||
# retrieve storage directory path
|
||||
storage_manager_path = get_storage_directory()
|
||||
|
||||
# generate full path of file
|
||||
file_path = os.path.join(
|
||||
storage_manager_path,
|
||||
unquote(file_data['file_name'])
|
||||
)
|
||||
file_data = None
|
||||
|
||||
# read file
|
||||
try:
|
||||
with open(file_path, 'r') as myfile:
|
||||
file_data = myfile.read()
|
||||
except IOError as e:
|
||||
# we don't want to expose real path of file
|
||||
# so only show error message.
|
||||
if e.strerror == 'Permission denied':
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
else:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
return internal_server_error(errormsg=err_msg)
|
||||
except Exception as e:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
return internal_server_error(errormsg=err_msg)
|
||||
return make_json_response(
|
||||
data={
|
||||
'status': True, 'result': file_data,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@blueprint.route('/save_file/', methods=["PUT", "POST"])
|
||||
@login_required
|
||||
def save_file():
|
||||
"""
|
||||
This function retrieves file_name and data from request.
|
||||
and then save the data to the file
|
||||
"""
|
||||
if request.data:
|
||||
file_data = json.loads(request.data.decode())
|
||||
|
||||
# retrieve storage directory path
|
||||
storage_manager_path = get_storage_directory()
|
||||
|
||||
# generate full path of file
|
||||
file_path = os.path.join(
|
||||
storage_manager_path,
|
||||
unquote(file_data['file_name'])
|
||||
)
|
||||
file_content = file_data['file_content']
|
||||
file_data = None
|
||||
|
||||
# write to file
|
||||
try:
|
||||
with open(file_path, 'w') as output_file:
|
||||
output_file.write(file_content)
|
||||
except IOError as e:
|
||||
if e.strerror == 'Permission denied':
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
else:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
return internal_server_error(errormsg=err_msg)
|
||||
except Exception as e:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
return internal_server_error(errormsg=err_msg)
|
||||
|
||||
return make_json_response(
|
||||
data={
|
||||
'status': True,
|
||||
}
|
||||
)
|
||||
|
@ -3,7 +3,7 @@ define(
|
||||
'codemirror/mode/sql/sql', 'codemirror/addon/selection/mark-selection', 'codemirror/addon/selection/active-line',
|
||||
'codemirror/addon/fold/foldgutter', 'codemirror/addon/fold/foldcode', 'codemirror/addon/fold/pgadmin-sqlfoldcode',
|
||||
'backgrid.select.all', 'backbone.paginator', 'backgrid.paginator', 'backgrid.filter',
|
||||
'bootstrap', 'pgadmin.browser', 'wcdocker'],
|
||||
'bootstrap', 'pgadmin.browser', 'wcdocker', 'pgadmin.file_manager'],
|
||||
function($, _, alertify, pgAdmin, Backbone, Backgrid, CodeMirror) {
|
||||
|
||||
// Some scripts do export their object in the window only.
|
||||
@ -143,6 +143,7 @@ define(
|
||||
|
||||
// Bind all the events
|
||||
events: {
|
||||
"click .btn-load-file": "on_file_load",
|
||||
"click #btn-save": "on_save",
|
||||
"click #btn-add-row": "on_add",
|
||||
"click #btn-filter": "on_show_filter",
|
||||
@ -641,7 +642,20 @@ define(
|
||||
},
|
||||
do_not_close_menu: function(ev) {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
// callback function for load file button click.
|
||||
on_file_load: function() {
|
||||
var self = this;
|
||||
|
||||
// Trigger the save signal to the SqlEditorController class
|
||||
self.handler.trigger(
|
||||
'pgadmin-sqleditor:button:load_file',
|
||||
self,
|
||||
self.handler
|
||||
);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
/* Defining controller class for data grid, which actually
|
||||
@ -683,11 +697,22 @@ define(
|
||||
self.transId = self.container.data('transId');
|
||||
|
||||
self.gridView.editor_title = editor_title;
|
||||
self.gridView.current_file = undefined;
|
||||
|
||||
// Render the header
|
||||
self.gridView.render();
|
||||
|
||||
// Listen to the file manager button events
|
||||
pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:select_file', self._select_file_handler, self);
|
||||
pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:create_file', self._save_file_handler, self);
|
||||
|
||||
// Listen to the codemirror on text change event
|
||||
// only in query editor tool
|
||||
if (self.is_query_tool)
|
||||
self.gridView.query_tool_obj.on('change', self._on_query_change, self);
|
||||
|
||||
// Listen on events come from SQLEditorView for the button clicked.
|
||||
self.on('pgadmin-sqleditor:button:load_file', self._load_file, self);
|
||||
self.on('pgadmin-sqleditor:button:save', self._save, self);
|
||||
self.on('pgadmin-sqleditor:button:addrow', self._add, self);
|
||||
self.on('pgadmin-sqleditor:button:show_filter', self._show_filter, self);
|
||||
@ -1297,12 +1322,34 @@ define(
|
||||
|
||||
/* This function will fetch the list of changed models and make
|
||||
* the ajax call to save the data into the database server.
|
||||
* and will open save file dialog conditionally.
|
||||
*/
|
||||
_save: function() {
|
||||
var self = this,
|
||||
data = [],
|
||||
save_data = true;
|
||||
|
||||
// Open save file dialog if query tool
|
||||
if (self.is_query_tool) {
|
||||
|
||||
var current_file = self.gridView.current_file;
|
||||
if (!_.isUndefined(current_file)) {
|
||||
self._save_file_handler(current_file);
|
||||
}
|
||||
else {
|
||||
// provide custom option to save file dialog
|
||||
var params = {
|
||||
'supported_types': ["*", "sql"],
|
||||
'dialog_type': 'create_file',
|
||||
'dialog_title': 'Save File',
|
||||
'btn_primary': 'Save'
|
||||
}
|
||||
pgAdmin.FileManager.init();
|
||||
pgAdmin.FileManager.show_dialog(params);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$("#btn-save").prop('disabled', true);
|
||||
if (self.changedModels.length == 0)
|
||||
return;
|
||||
@ -1395,6 +1442,87 @@ define(
|
||||
}
|
||||
},
|
||||
|
||||
// load select file dialog
|
||||
_load_file: function() {
|
||||
var params = {
|
||||
'supported_types': ["sql"], // file types allowed
|
||||
'dialog_type': 'select_file' // open select file dialog
|
||||
}
|
||||
pgAdmin.FileManager.init();
|
||||
pgAdmin.FileManager.show_dialog(params);
|
||||
},
|
||||
|
||||
// read file data and return as response
|
||||
_select_file_handler: function(e) {
|
||||
var self = this;
|
||||
|
||||
data = {
|
||||
'file_name': e
|
||||
}
|
||||
|
||||
// Make ajax call to load the data from file
|
||||
$.ajax({
|
||||
url: "{{ url_for('sqleditor.index') }}" + "load_file/",
|
||||
method: 'POST',
|
||||
async: false,
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(data),
|
||||
success: function(res) {
|
||||
if (res.data.status) {
|
||||
self.gridView.query_tool_obj.setValue(res.data.result);
|
||||
self.gridView.current_file = e;
|
||||
}
|
||||
},
|
||||
error: function(e) {
|
||||
var errmsg = $.parseJSON(e.responseText).errormsg;
|
||||
alertify.error(errmsg);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// read data from codemirror and write to file
|
||||
_save_file_handler: function(e) {
|
||||
var self = this;
|
||||
data = {
|
||||
'file_name': e,
|
||||
'file_content': self.gridView.query_tool_obj.getValue()
|
||||
}
|
||||
|
||||
// Make ajax call to save the data to file
|
||||
$.ajax({
|
||||
url: "{{ url_for('sqleditor.index') }}" + "save_file/",
|
||||
method: 'POST',
|
||||
async: false,
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(data),
|
||||
success: function(res) {
|
||||
if (res.data.status) {
|
||||
alertify.success('{{ _('File saved successfully.') }}');
|
||||
self.gridView.current_file = e;
|
||||
|
||||
// disable save button on file save
|
||||
$("#btn-save").prop('disabled', true);
|
||||
}
|
||||
},
|
||||
error: function(e) {
|
||||
var errmsg = $.parseJSON(e.responseText).errormsg;
|
||||
alertify.error(errmsg);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// codemirror text change event
|
||||
_on_query_change: function(query_tool_obj) {
|
||||
|
||||
if(query_tool_obj.getValue().length == 0) {
|
||||
$("#btn-save").prop('disabled', true);
|
||||
}
|
||||
else {
|
||||
$("#btn-save").prop('disabled', false);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// This function will run the SQL query and refresh the data in the backgrid.
|
||||
_refresh: function() {
|
||||
var self = this;
|
||||
@ -1696,6 +1824,7 @@ define(
|
||||
$("#btn-query-dropdown").prop('disabled', disabled);
|
||||
$("#btn-edit-dropdown").prop('disabled', disabled);
|
||||
$("#btn-edit").prop('disabled', disabled);
|
||||
$('#btn-load-file').prop('disabled', disabled);
|
||||
},
|
||||
|
||||
// This function will fetch the sql query from the text box
|
||||
|
Loading…
Reference in New Issue
Block a user