Fixed the following SonarQube code smells:
1) Do not use Array index in keys. 2) Unnecessary escape character. 3) Rename this local variable to match the regular expression ^[_a-z][a-z0-9_]*$ 4) Remove the unused local variable.pull/6437/head
parent
3e713cf58b
commit
251bf05692
|
@ -11,6 +11,7 @@ notes for it.
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
release_notes_7_4
|
||||
release_notes_7_3
|
||||
release_notes_7_2
|
||||
release_notes_7_1
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
***********
|
||||
Version 7.4
|
||||
***********
|
||||
|
||||
Release date: 2023-06-29
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v7.3.
|
||||
|
||||
Supported Database Servers
|
||||
**************************
|
||||
**PostgreSQL**: 11, 12, 13, 14 and 15
|
||||
|
||||
**EDB Advanced Server**: 11, 12, 13, 14 and 15
|
||||
|
||||
Bundled PostgreSQL Utilities
|
||||
****************************
|
||||
**psql**, **pg_dump**, **pg_dumpall**, **pg_restore**: 15.3
|
||||
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #6065 <https://github.com/pgadmin-org/pgadmin4/issues/6065>`_ - Ensure that query tool shortcuts are working properly.
|
||||
| `Issue #6363 <https://github.com/pgadmin-org/pgadmin4/issues/6363>`_ - Fixed an issue where preview images for themes were not loading.
|
|
@ -359,7 +359,6 @@ class TriggerView(PGChildNodeView, SchemaDiffObjectCompare):
|
|||
"""
|
||||
res = [{'label': '', 'value': ''}]
|
||||
|
||||
# TODO: REMOVE True Condition , it's just for testing
|
||||
# If server type is EDB-PPAS then we also need to add
|
||||
# inline edb-spl along with options fetched by below sql
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ export function Search({closeModal}) {
|
|||
let menuItemsHtmlElement = [];
|
||||
items.forEach((i) => {
|
||||
menuItemsHtmlElement.push(
|
||||
<li key={ 'li-menu-' + i }><a tabIndex='0' id={ 'li-menu-' + i.label } href={'#'} className={ (i.isDisabled ? 'dropdown-item menu-groups-a disabled':'dropdown-item menu-groups-a')} key={ 'menu-' + i.label } onClick={
|
||||
<li key={ 'li-menu-' + i.label }><a tabIndex='0' id={ 'li-menu-' + i.label } href={'#'} className={ (i.isDisabled ? 'dropdown-item menu-groups-a disabled':'dropdown-item menu-groups-a')} onClick={
|
||||
() => {
|
||||
closeModal();
|
||||
i.callback();
|
||||
|
@ -257,7 +257,7 @@ export function Search({closeModal}) {
|
|||
</div>
|
||||
|
||||
{Object.keys(helpSearchResult.data).map( (value, index) => {
|
||||
if(index <= 9) { return <li key={ 'li-help-' + index }><a tabIndex='0' href={helpSearchResult.data[value]} key={ 'help-' + index } className='dropdown-item' target='_blank' rel='noreferrer'>{value}</a></li>; }
|
||||
if(index <= 9) { return <li key={ 'li-help-' + value }><a tabIndex='0' href={helpSearchResult.data[value]} className='dropdown-item' target='_blank' rel='noreferrer'>{value}</a></li>; }
|
||||
})}
|
||||
|
||||
{(Object.keys(helpSearchResult.data).length == 0) ? (<div className='pad-12 no-results'><span className='fa fa-info-circle'></span> {gettext('No search results')}</div>):''}
|
||||
|
|
|
@ -861,7 +861,7 @@ export default function Dashboard({
|
|||
controlProps={CustomActiveOnlyHeaderLabel}
|
||||
></InputCheckbox>);
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{sid && props.serverConnected ? (
|
||||
|
@ -890,8 +890,8 @@ export default function Dashboard({
|
|||
value={tabVal}
|
||||
onChange={tabChanged}
|
||||
>
|
||||
{tabs.map((tabValue, i) => {
|
||||
return <Tab key={i} label={tabValue} />;
|
||||
{tabs.map((tabValue) => {
|
||||
return <Tab key={tabValue} label={tabValue} />;
|
||||
})}
|
||||
<RefreshButton/>
|
||||
</Tabs>
|
||||
|
@ -961,8 +961,8 @@ export function ChartContainer(props) {
|
|||
<div id={props.id}>{props.title}</div>
|
||||
<div className={classes.chartLegend}>
|
||||
<div className="d-flex">
|
||||
{props.datasets?.map((datum, i)=>(
|
||||
<div className="legend-value" key={i}>
|
||||
{props.datasets?.map((datum)=>(
|
||||
<div className="legend-value" key={datum.label}>
|
||||
<span style={{backgroundColor: datum.borderColor}}> </span>
|
||||
<span className="legend-label">{datum.label}</span>
|
||||
</div>
|
||||
|
|
|
@ -175,11 +175,12 @@ export default function ProcessDetails({data}) {
|
|||
{logs == null && <span data-test="loading-logs">{gettext('Loading process logs...')}</span>}
|
||||
{logs?.length == 0 && gettext('No logs available.')}
|
||||
{logs?.map((log, i)=>{
|
||||
let id = logs.length-i;
|
||||
return <div ref={(el)=>{
|
||||
if(i==logs.length-1) {
|
||||
el?.scrollIntoView();
|
||||
}
|
||||
}} key={i} className={errRe.test(log) ? classes.logErr : ''}>{log}</div>;
|
||||
}} key={id} className={errRe.test(log) ? classes.logErr : ''}>{log}</div>;
|
||||
})}
|
||||
</Box>
|
||||
<Box display="flex" alignItems="center">
|
||||
|
|
|
@ -166,7 +166,7 @@ class DatabaseSchema extends BaseUISchema {
|
|||
}, {
|
||||
id: 'db_password', label: gettext('Password'), type: 'password',
|
||||
mode: ['create'], noEmpty: true,
|
||||
helpMessage: gettext('At least 8 printable ASCII characters. Cannot contain any of the following: / \(slash\), \'\(single quote\), "\(double quote\) and @ \(at sign\).')
|
||||
helpMessage: gettext('At least 8 printable ASCII characters. Cannot contain any of the following: / (slash), \'(single quote), "(double quote) and @ (at sign).')
|
||||
}, {
|
||||
id: 'db_confirm_password', label: gettext('Confirm password'),
|
||||
type: 'password',
|
||||
|
|
|
@ -104,7 +104,7 @@ export function FinalSummary(props) {
|
|||
|
||||
return summary.map((item, index) => {
|
||||
return (
|
||||
<Table key={index} className={clsx(tableClasses.table)}>
|
||||
<Table key={summaryHeader[index]} className={clsx(tableClasses.table)}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell colSpan={2}>{gettext(summaryHeader[index])}</TableCell>
|
||||
|
|
|
@ -311,7 +311,7 @@ class Filemanager():
|
|||
def __init__(self, trans_id, ss=''):
|
||||
self.trans_id = trans_id
|
||||
self.dir = get_storage_directory()
|
||||
self.sharedDir = get_storage_directory(shared_storage=ss)
|
||||
self.shared_dir = get_storage_directory(shared_storage=ss)
|
||||
|
||||
if self.dir is not None and isinstance(self.dir, list):
|
||||
self.dir = ""
|
||||
|
@ -409,10 +409,10 @@ class Filemanager():
|
|||
last_ss_name = blueprint.last_storage.get()
|
||||
if last_ss_name and last_ss_name != MY_STORAGE \
|
||||
and len(config.SHARED_STORAGE) > 0:
|
||||
selectedDir = [sdir for sdir in config.SHARED_STORAGE if
|
||||
sdir['name'] == last_ss_name]
|
||||
last_ss = selectedDir[0]['path'] if len(
|
||||
selectedDir) == 1 else storage_dir
|
||||
selected_dir = [sdir for sdir in config.SHARED_STORAGE if
|
||||
sdir['name'] == last_ss_name]
|
||||
last_ss = selected_dir[0]['path'] if len(
|
||||
selected_dir) == 1 else storage_dir
|
||||
else:
|
||||
if last_ss_name != MY_STORAGE:
|
||||
last_dir = '/'
|
||||
|
@ -770,8 +770,8 @@ class Filemanager():
|
|||
trans_data = Filemanager.get_trasaction_selection(self.trans_id)
|
||||
the_dir = None
|
||||
if config.SERVER_MODE:
|
||||
if self.sharedDir and len(config.SHARED_STORAGE) > 0:
|
||||
the_dir = self.sharedDir
|
||||
if self.shared_dir and len(config.SHARED_STORAGE) > 0:
|
||||
the_dir = self.shared_dir
|
||||
else:
|
||||
the_dir = self.dir
|
||||
|
||||
|
@ -782,18 +782,16 @@ class Filemanager():
|
|||
the_dir, path, trans_data, file_type, show_hidden)
|
||||
return filelist
|
||||
|
||||
def check_access(self, ss, mode):
|
||||
if self.sharedDir:
|
||||
selectedDirList = [sdir for sdir in config.SHARED_STORAGE if
|
||||
sdir['name'] == ss]
|
||||
selectedDir = selectedDirList[0] if len(
|
||||
selectedDirList) == 1 else None
|
||||
def check_access(self, ss):
|
||||
if self.shared_dir:
|
||||
selected_dir_list = [sdir for sdir in config.SHARED_STORAGE if
|
||||
sdir['name'] == ss]
|
||||
selected_dir = selected_dir_list[0] if len(
|
||||
selected_dir_list) == 1 else None
|
||||
|
||||
if selectedDir:
|
||||
if selectedDir[
|
||||
'restricted_access'] and not current_user.has_role(
|
||||
"Administrator"):
|
||||
raise PermissionError(ACCESS_DENIED_MESSAGE)
|
||||
if selected_dir and selected_dir['restricted_access'] and \
|
||||
not current_user.has_role("Administrator"):
|
||||
raise PermissionError(ACCESS_DENIED_MESSAGE)
|
||||
|
||||
def rename(self, old=None, new=None):
|
||||
"""
|
||||
|
@ -802,8 +800,8 @@ class Filemanager():
|
|||
if not self.validate_request('rename'):
|
||||
return unauthorized(self.ERROR_NOT_ALLOWED['Error'])
|
||||
|
||||
if self.sharedDir:
|
||||
the_dir = self.sharedDir
|
||||
if self.shared_dir:
|
||||
the_dir = self.shared_dir
|
||||
else:
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
|
||||
|
@ -848,8 +846,8 @@ class Filemanager():
|
|||
"""
|
||||
if not self.validate_request('delete'):
|
||||
return unauthorized(self.ERROR_NOT_ALLOWED['Error'])
|
||||
if self.sharedDir:
|
||||
the_dir = self.sharedDir
|
||||
if self.shared_dir:
|
||||
the_dir = self.shared_dir
|
||||
else:
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
orig_path = "{0}{1}".format(the_dir, path)
|
||||
|
@ -874,8 +872,8 @@ class Filemanager():
|
|||
if not self.validate_request('upload'):
|
||||
return unauthorized(self.ERROR_NOT_ALLOWED['Error'])
|
||||
|
||||
if self.sharedDir:
|
||||
the_dir = self.sharedDir
|
||||
if self.shared_dir:
|
||||
the_dir = self.shared_dir
|
||||
else:
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
|
||||
|
@ -1042,8 +1040,8 @@ class Filemanager():
|
|||
if not self.validate_request('create'):
|
||||
return unauthorized(self.ERROR_NOT_ALLOWED['Error'])
|
||||
|
||||
if self.sharedDir and len(config.SHARED_STORAGE) > 0:
|
||||
user_dir = self.sharedDir
|
||||
if self.shared_dir and len(config.SHARED_STORAGE) > 0:
|
||||
user_dir = self.shared_dir
|
||||
else:
|
||||
user_dir = self.dir if self.dir is not None else ''
|
||||
|
||||
|
@ -1073,8 +1071,8 @@ class Filemanager():
|
|||
if not self.validate_request('download'):
|
||||
return unauthorized(self.ERROR_NOT_ALLOWED['Error'])
|
||||
|
||||
if self.sharedDir and len(config.SHARED_STORAGE) > 0:
|
||||
the_dir = self.sharedDir
|
||||
if self.shared_dir and len(config.SHARED_STORAGE) > 0:
|
||||
the_dir = self.shared_dir
|
||||
else:
|
||||
the_dir = self.dir if self.dir is not None else ''
|
||||
|
||||
|
@ -1139,7 +1137,7 @@ def file_manager(trans_id):
|
|||
|
||||
if ss and mode in ['upload', 'rename', 'delete', 'addfolder', 'add',
|
||||
'permission']:
|
||||
my_fm.check_access(ss, mode)
|
||||
my_fm.check_access(ss)
|
||||
func = getattr(my_fm, mode)
|
||||
try:
|
||||
if mode in ['getfolder', 'download']:
|
||||
|
|
|
@ -81,7 +81,7 @@ export function ItemView({idx, row, selected, onItemSelect, onItemEnter, onEditC
|
|||
onEditComplete(row);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let icon = <DescriptionIcon style={{fontSize: '2.5rem'}} />;
|
||||
if(row.file_type == 'dir') {
|
||||
icon = <FolderIcon style={{fontSize: '2.5rem'}} />;
|
||||
|
@ -133,7 +133,7 @@ export default function GridView({items, operation, onItemSelect, onItemEnter})
|
|||
<Box flexGrow={1} overflow="hidden auto">
|
||||
<ul ref={gridRef} className={classes.grid}>
|
||||
{items.map((item, i)=>(
|
||||
<ItemView key={i} idx={i} row={item} selected={selectedIdx==i} onItemSelect={setSelectedIdx}
|
||||
<ItemView key={item.Filename} idx={i} row={item} selected={selectedIdx==i} onItemSelect={setSelectedIdx}
|
||||
onItemEnter={onItemEnter} onEditComplete={operation.idx==i ? onEditComplete : null} />)
|
||||
)}
|
||||
</ul>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { Box, makeStyles } from '@material-ui/core';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { PrimaryButton } from './components/Buttons';
|
||||
import { PgMenu, PgMenuDivider, PgMenuItem, PgSubMenu } from './components/Menu';
|
||||
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
|
||||
import AccountCircleRoundedIcon from '@material-ui/icons/AccountCircleRounded';
|
||||
import pgAdmin from 'sources/pgadmin';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const useStyles = makeStyles((theme)=>({
|
||||
root: {
|
||||
|
@ -96,17 +95,17 @@ export default function AppMenuBar() {
|
|||
<Box className={classes.root}>
|
||||
<div className={classes.logo} />
|
||||
<div className={classes.menus}>
|
||||
{pgAdmin.Browser.MainMenus?.map((menu, i)=>{
|
||||
{pgAdmin.Browser.MainMenus?.map((menu)=>{
|
||||
return (
|
||||
<PgMenu
|
||||
menuButton={<PrimaryButton key={i} className={classes.menuButton} data-label={menu.label}>{menu.label}<KeyboardArrowDownIcon fontSize="small" /></PrimaryButton>}
|
||||
menuButton={<PrimaryButton key={menu.label} className={classes.menuButton} data-label={menu.label}>{menu.label}<KeyboardArrowDownIcon fontSize="small" /></PrimaryButton>}
|
||||
label={menu.label}
|
||||
key={menu.name}
|
||||
>
|
||||
{menu.getMenuItems().map((menuItem, i)=>{
|
||||
const submenus = menuItem.getMenuItems();
|
||||
if(submenus) {
|
||||
return <PgSubMenu key={i} label={menuItem.label}>
|
||||
return <PgSubMenu key={menuItem.label} label={menuItem.label}>
|
||||
{submenus.map((submenuItem, si)=>{
|
||||
return getPgMenuItem(submenuItem, si);
|
||||
})}
|
||||
|
|
|
@ -195,8 +195,8 @@ export default function Analysis({explainTable}) {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{_.sortBy(explainTable.rows,(r)=>r['data']['_serial']).map((row, i)=>{
|
||||
return <ExplainRow key={i} row={row} show={{
|
||||
{_.sortBy(explainTable.rows,(r)=>r['data']['_serial']).map((row)=>{
|
||||
return <ExplainRow key={row?.data?.arr_id} row={row} show={{
|
||||
show_timings: explainTable.show_timings,
|
||||
show_rowsx: explainTable.show_rowsx,
|
||||
show_rows: explainTable.show_rows,
|
||||
|
|
|
@ -635,7 +635,7 @@ export default function DataGridView({
|
|||
<div {...getTableBodyProps()} className={classes.tableContentWidth}>
|
||||
{rows.map((row, i) => {
|
||||
prepareRow(row);
|
||||
return <React.Fragment key={i}>
|
||||
return <React.Fragment key={row.index}>
|
||||
<DataTableRow index={i} row={row} totalRows={rows.length} isResizing={isResizing}
|
||||
schema={schemaRef.current} schemaRef={schemaRef} accessPath={accessPath.concat([row.index])}
|
||||
moveRow={moveRow} isHovered={i == hoverIndex} setHoverIndex={setHoverIndex} />
|
||||
|
|
|
@ -44,7 +44,6 @@ export default function ObjectBreadcrumbs({pgAdmin}) {
|
|||
description: null,
|
||||
});
|
||||
const onItemHover = (item, _data)=>{
|
||||
// if(!checkIsMounted) return;
|
||||
if(item && !_data?._type.startsWith('coll-')) {
|
||||
setObjectData({
|
||||
path: pgAdmin.Browser.tree.getNodeDisplayPath(item, false),
|
||||
|
@ -99,8 +98,8 @@ export default function ObjectBreadcrumbs({pgAdmin}) {
|
|||
<AccountTreeIcon style={{height: '1rem', marginRight: '0.125rem'}} />
|
||||
<div className={classes.overflow}>
|
||||
{
|
||||
objectData.path?.reduce((res, item, i)=>(
|
||||
res.concat(<span key={i}>{item}</span>, <ArrowForwardIosRoundedIcon key={i+'-arrow'} style={{height: '0.8rem', width: '1.25rem'}} />)
|
||||
objectData.path?.reduce((res, item)=>(
|
||||
res.concat(<span key={item}>{item}</span>, <ArrowForwardIosRoundedIcon key={item+'-arrow'} style={{height: '0.8rem', width: '1.25rem'}} />)
|
||||
), []).slice(0, -1)
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -73,8 +73,8 @@ export default function ShortcutTitle({title, shortcut, accesskey}) {
|
|||
<>
|
||||
<div className={classes.shortcutTitle}>{title}</div>
|
||||
<div className={classes.shortcut}>
|
||||
{keys.map((key, i)=>{
|
||||
return <div key={i} className={classes.key}>{key}</div>;
|
||||
{keys.map((key)=>{
|
||||
return <div key={key} className={classes.key}>{key}</div>;
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
|
|
|
@ -99,7 +99,6 @@ class IEMessage(IProcessDesc):
|
|||
|
||||
if s is None:
|
||||
return _("Not available")
|
||||
server_str = '{0}'.format(s.name)
|
||||
host_port_str = ''
|
||||
if s.host:
|
||||
host_port_str = '({0}:{1})'.format(
|
||||
|
|
|
@ -21,7 +21,7 @@ export default class ImportExportSchema extends BaseUISchema {
|
|||
oid: undefined,
|
||||
header: undefined,
|
||||
delimiter: ',',
|
||||
quote: '\"',
|
||||
quote: '"',
|
||||
escape: '\'',
|
||||
file: undefined,
|
||||
format: 'csv',
|
||||
|
@ -156,8 +156,8 @@ export default class ImportExportSchema extends BaseUISchema {
|
|||
type: 'select',
|
||||
controlProps: {creatable: true},
|
||||
options: [{
|
||||
'label': '\"',
|
||||
'value': '\"',
|
||||
'label': '"',
|
||||
'value': '"',
|
||||
},
|
||||
{
|
||||
'label': '\'',
|
||||
|
@ -174,8 +174,8 @@ export default class ImportExportSchema extends BaseUISchema {
|
|||
type: 'select',
|
||||
controlProps: {creatable: true},
|
||||
options: [{
|
||||
'label': '\"',
|
||||
'value': '\"',
|
||||
'label': '"',
|
||||
'value': '"',
|
||||
},
|
||||
{
|
||||
'label': '\'',
|
||||
|
|
|
@ -117,9 +117,6 @@ def load_servers():
|
|||
|
||||
file_path = unquote(filename)
|
||||
|
||||
# retrieve storage directory path
|
||||
storage_manager_path = get_storage_directory()
|
||||
|
||||
try:
|
||||
file_path = filename_with_file_manager_path(file_path)
|
||||
except PermissionError as e:
|
||||
|
|
|
@ -228,8 +228,6 @@ export function initialize(gettext, url_for, _, pgAdmin, csrfToken, Browser) {
|
|||
let db_label = '';
|
||||
if(pData.database && pData.database._id) {
|
||||
db_label = _.escape(pData.database._label.replace('\\', '\\\\'));
|
||||
db_label = db_label.replace('\'', '\'');
|
||||
db_label = db_label.replace('"', '\"');
|
||||
openUrl += `&db=${db_label}`;
|
||||
} else {
|
||||
openUrl += `&db=${''}`;
|
||||
|
|
|
@ -253,7 +253,7 @@ def set_multiple(key, param, data, args, driver, conn, with_schema=True):
|
|||
if key in data and \
|
||||
len(data[key]) > 0:
|
||||
if with_schema:
|
||||
# TODO:// This is temporary
|
||||
# This is temporary
|
||||
# Once object tree is implemented then we will use
|
||||
# list of tuples 'else' part
|
||||
_set_value_with_schema(data, key, args, param, driver, conn)
|
||||
|
|
|
@ -564,6 +564,7 @@ def compare_database(params):
|
|||
|
||||
msg = gettext("Successfully compare the specified databases.")
|
||||
total_percent = 100
|
||||
diff_model_obj.set_comparison_info(msg, total_percent)
|
||||
# Update the message and total percentage done in session object
|
||||
update_session_diff_transaction(params['trans_id'], session_obj,
|
||||
diff_model_obj)
|
||||
|
@ -626,6 +627,7 @@ def compare_schema(params):
|
|||
|
||||
msg = gettext("Successfully compare the specified schemas.")
|
||||
total_percent = 100
|
||||
diff_model_obj.set_comparison_info(msg, total_percent)
|
||||
# Update the message and total percentage done in session object
|
||||
update_session_diff_transaction(params['trans_id'], session_obj,
|
||||
diff_model_obj)
|
||||
|
|
|
@ -627,7 +627,6 @@ def directory_diff(source_dict, target_dict, ignore_keys=[], difference=None):
|
|||
for index in range(len(source_dict[key])):
|
||||
source = copy.deepcopy(source_dict[key][index])
|
||||
if isinstance(source, list):
|
||||
# TODO
|
||||
pass
|
||||
elif isinstance(source, dict):
|
||||
# Check the above keys are exist in the dictionary
|
||||
|
|
|
@ -1860,18 +1860,17 @@ def save_file():
|
|||
last_storage = Preferences.module('file_manager').preference(
|
||||
'last_storage').get()
|
||||
if last_storage != MY_STORAGE:
|
||||
selectedDirList = [sdir for sdir in SHARED_STORAGE if
|
||||
sdir['name'] == last_storage]
|
||||
selectedDir = selectedDirList[0] if len(
|
||||
selectedDirList) == 1 else None
|
||||
selected_dir_list = [sdir for sdir in SHARED_STORAGE if
|
||||
sdir['name'] == last_storage]
|
||||
selected_dir = selected_dir_list[0] if len(
|
||||
selected_dir_list) == 1 else None
|
||||
|
||||
if selectedDir:
|
||||
if selectedDir['restricted_access'] and \
|
||||
not current_user.has_role("Administrator"):
|
||||
return make_json_response(success=0,
|
||||
errormsg=ACCESS_DENIED_MESSAGE,
|
||||
info='ACCESS_DENIED',
|
||||
status=403)
|
||||
if selected_dir and selected_dir['restricted_access'] and \
|
||||
not current_user.has_role("Administrator"):
|
||||
return make_json_response(success=0,
|
||||
errormsg=ACCESS_DENIED_MESSAGE,
|
||||
info='ACCESS_DENIED',
|
||||
status=403)
|
||||
storage_manager_path = get_storage_directory(
|
||||
shared_storage=last_storage)
|
||||
else:
|
||||
|
|
|
@ -632,7 +632,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
|
|||
>
|
||||
<PgMenuItem onClick={onManageMacros}>{gettext('Manage macros')}</PgMenuItem>
|
||||
<PgMenuDivider />
|
||||
{queryToolCtx.params?.macros?.map((m, i)=>{
|
||||
{queryToolCtx.params?.macros?.map((m)=>{
|
||||
return (
|
||||
<PgMenuItem shortcut={{
|
||||
...m,
|
||||
|
@ -640,7 +640,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
|
|||
'key_code': m.key_code,
|
||||
'char': m.key,
|
||||
},
|
||||
}} onClick={()=>executeMacro(m)} key={i}>
|
||||
}} onClick={()=>executeMacro(m)} key={m.name}>
|
||||
{m.name}
|
||||
</PgMenuItem>
|
||||
);
|
||||
|
|
|
@ -45,8 +45,8 @@ export function Notifications() {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{notices.map((notice, i)=>{
|
||||
return <tr key={i}>
|
||||
{notices.map((notice)=>{
|
||||
return <tr key={notice.pid}>
|
||||
<td data-label="recorded_time">{notice.recorded_time}</td>
|
||||
<td data-label="channel">{notice.channel}</td>
|
||||
<td data-label="pid">{notice.pid}</td>
|
||||
|
|
|
@ -17,8 +17,6 @@ def apply_explain_plan_wrapper_if_needed(manager, sql):
|
|||
if 'explain_plan' in sql and sql['explain_plan']:
|
||||
explain_plan = sql['explain_plan']
|
||||
ver = manager.version if manager.version is not None else 0
|
||||
server_type = \
|
||||
manager.server_type if manager.server_type is not None else 'pg'
|
||||
template_path = compile_template_name(
|
||||
'sqleditor/sql',
|
||||
'explain_plan.sql',
|
||||
|
|
|
@ -267,7 +267,8 @@ def filename_with_file_manager_path(_file, create_file=False,
|
|||
"""
|
||||
Args:
|
||||
file: File name returned from client file manager
|
||||
create_file: Set flag to False when file creation doesn't required
|
||||
create_file: Set flag to False when file creation doesn't require
|
||||
skip_permission_check:
|
||||
Returns:
|
||||
Filename to use for backup with full path taken from preference
|
||||
"""
|
||||
|
@ -275,22 +276,21 @@ def filename_with_file_manager_path(_file, create_file=False,
|
|||
try:
|
||||
last_storage = Preferences.module('file_manager').preference(
|
||||
'last_storage').get()
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
last_storage = MY_STORAGE
|
||||
|
||||
if last_storage != MY_STORAGE:
|
||||
selDirList = [sdir for sdir in current_app.config['SHARED_STORAGE']
|
||||
if sdir['name'] == last_storage]
|
||||
selectedDir = selDirList[0] if len(
|
||||
selDirList) == 1 else None
|
||||
sel_dir_list = [sdir for sdir in current_app.config['SHARED_STORAGE']
|
||||
if sdir['name'] == last_storage]
|
||||
selected_dir = sel_dir_list[0] if len(
|
||||
sel_dir_list) == 1 else None
|
||||
|
||||
if selectedDir:
|
||||
if selectedDir['restricted_access'] and \
|
||||
not current_user.has_role("Administrator"):
|
||||
return make_json_response(success=0,
|
||||
errormsg=ACCESS_DENIED_MESSAGE,
|
||||
info='ACCESS_DENIED',
|
||||
status=403)
|
||||
if selected_dir and selected_dir['restricted_access'] and \
|
||||
not current_user.has_role("Administrator"):
|
||||
return make_json_response(success=0,
|
||||
errormsg=ACCESS_DENIED_MESSAGE,
|
||||
info='ACCESS_DENIED',
|
||||
status=403)
|
||||
storage_dir = get_storage_directory(
|
||||
shared_storage=last_storage)
|
||||
else:
|
||||
|
|
|
@ -800,14 +800,12 @@ WHERE db.datname = current_database()""")
|
|||
query = query.encode(self.python_encoding)
|
||||
cur.execute(query, params)
|
||||
|
||||
def execute_on_server_as_csv(self, formatted_exception_msg=False,
|
||||
records=2000):
|
||||
def execute_on_server_as_csv(self, records=2000):
|
||||
"""
|
||||
To fetch query result and generate CSV output
|
||||
|
||||
Args:
|
||||
params: Additional parameters
|
||||
formatted_exception_msg: For exception
|
||||
records: Number of initial records
|
||||
Returns:
|
||||
Generator response
|
||||
|
@ -1011,7 +1009,7 @@ WHERE db.datname = current_database()""")
|
|||
# If multiple queries are run, make sure to reach
|
||||
# the last query result
|
||||
while cur.nextset():
|
||||
pass
|
||||
pass # This loop is empty
|
||||
|
||||
self.row_count = cur.get_rowcount()
|
||||
if cur.get_rowcount() > 0:
|
||||
|
@ -1444,10 +1442,10 @@ Failed to reset the connection to the server due to following error:
|
|||
asyncio.run(_close_conn(self.conn))
|
||||
|
||||
def _wait(self, conn):
|
||||
pass
|
||||
pass # This function is empty
|
||||
|
||||
def _wait_timeout(self, conn):
|
||||
pass
|
||||
pass # This function is empty
|
||||
|
||||
def poll(self, formatted_exception_msg=False, no_result=False):
|
||||
cur = self.__async_cursor
|
||||
|
@ -1474,9 +1472,8 @@ Failed to reset the connection to the server due to following error:
|
|||
while more_result:
|
||||
if not self.conn.pgconn.is_busy():
|
||||
if cur.description is not None:
|
||||
for desc in cur.ordered_description():
|
||||
self.column_info = [desc.to_dict() for
|
||||
desc in cur.ordered_description()]
|
||||
self.column_info = [desc.to_dict() for
|
||||
desc in cur.ordered_description()]
|
||||
|
||||
pos = 0
|
||||
if self.column_info:
|
||||
|
|
|
@ -389,7 +389,7 @@ WHERE db.oid = {0}""".format(did))
|
|||
conn = self.connections[conn_id]
|
||||
# only try to reconnect if connection was connected previously
|
||||
# and auto_reconnect is true.
|
||||
wasConnected = conn.wasConnected
|
||||
was_connected = conn.wasConnected
|
||||
auto_reconnect = conn.auto_reconnect
|
||||
if conn.wasConnected and conn.auto_reconnect:
|
||||
try:
|
||||
|
@ -409,7 +409,7 @@ WHERE db.oid = {0}""".format(did))
|
|||
except CryptKeyMissing:
|
||||
# maintain the status as this will help to restore once
|
||||
# the key is available
|
||||
conn.wasConnected = wasConnected
|
||||
conn.wasConnected = was_connected
|
||||
conn.auto_reconnect = auto_reconnect
|
||||
except Exception as e:
|
||||
self.connections.pop(conn_id)
|
||||
|
|
|
@ -17,6 +17,8 @@ from werkzeug.exceptions import InternalServerError
|
|||
from pgadmin.utils.constants import MY_STORAGE
|
||||
from pgadmin.model import User
|
||||
|
||||
PGADMIN_PATH = '~/.pgadmin/'
|
||||
|
||||
|
||||
def preprocess_username(un):
|
||||
ret_un = un
|
||||
|
@ -40,18 +42,18 @@ def get_storage_directory(user=current_user, shared_storage=''):
|
|||
is_shared_storage = False
|
||||
if shared_storage != MY_STORAGE and shared_storage:
|
||||
is_shared_storage = True
|
||||
selectedDir = [sdir for sdir in config.SHARED_STORAGE if
|
||||
sdir['name'] == shared_storage]
|
||||
selected_dir = [sdir for sdir in config.SHARED_STORAGE if
|
||||
sdir['name'] == shared_storage]
|
||||
storage_dir = None
|
||||
if len(selectedDir) > 0:
|
||||
the_dir = selectedDir[0]['path']
|
||||
if len(selected_dir) > 0:
|
||||
the_dir = selected_dir[0]['path']
|
||||
storage_dir = the_dir
|
||||
else:
|
||||
storage_dir = getattr(
|
||||
config, 'STORAGE_DIR',
|
||||
os.path.join(
|
||||
os.path.realpath(
|
||||
os.path.expanduser('~/.pgadmin/')
|
||||
os.path.expanduser(PGADMIN_PATH)
|
||||
), 'storage'
|
||||
)
|
||||
)
|
||||
|
@ -109,7 +111,7 @@ def init_app():
|
|||
config, 'STORAGE_DIR',
|
||||
os.path.join(
|
||||
os.path.realpath(
|
||||
os.path.expanduser('~/.pgadmin/')
|
||||
os.path.expanduser(PGADMIN_PATH)
|
||||
), 'storage'
|
||||
)
|
||||
)
|
||||
|
@ -159,7 +161,7 @@ def create_users_storage_directory():
|
|||
config, 'STORAGE_DIR',
|
||||
os.path.join(
|
||||
os.path.realpath(
|
||||
os.path.expanduser('~/.pgadmin/')
|
||||
os.path.expanduser(PGADMIN_PATH)
|
||||
), 'storage'
|
||||
)
|
||||
)
|
||||
|
|
|
@ -45,7 +45,6 @@ class QueryToolFeatureTest(BaseFeatureTest):
|
|||
|
||||
def runTest(self):
|
||||
self._reset_options()
|
||||
skip_warning = "Skipped."
|
||||
# on demand result set on scrolling.
|
||||
print("\nOn demand query result... ",
|
||||
file=sys.stderr, end="")
|
||||
|
|
Loading…
Reference in New Issue