2018-02-27 05:18:36 -06:00
//////////////////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
2022-01-04 02:24:25 -06:00
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
2018-02-27 05:18:36 -06:00
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////////////////
2022-07-19 04:57:47 -05:00
import _ from 'lodash' ;
2020-04-14 03:02:03 -05:00
import $ from 'jquery' ;
2022-12-08 07:47:12 -06:00
import url _for from './url_for' ;
2021-06-04 07:25:35 -05:00
import gettext from 'sources/gettext' ;
2021-06-25 01:08:02 -05:00
import 'wcdocker' ;
2021-12-07 07:22:40 -06:00
import Notify from './helpers/Notifier' ;
2022-05-23 05:34:21 -05:00
import { hasTrojanSource } from 'anti-trojan-source' ;
2022-08-09 05:12:16 -05:00
import convert from 'convert-units' ;
2022-12-08 07:47:12 -06:00
import getApiInstance from './api_instance' ;
2021-06-25 01:08:02 -05:00
2022-09-08 07:38:58 -05:00
let wcDocker = window . wcDocker ;
2018-07-25 01:40:46 -05:00
2018-02-27 05:18:36 -06:00
export function parseShortcutValue ( obj ) {
2022-09-08 07:38:58 -05:00
let shortcut = '' ;
2018-02-27 05:18:36 -06:00
if ( obj . alt ) { shortcut += 'alt+' ; }
if ( obj . shift ) { shortcut += 'shift+' ; }
if ( obj . control ) { shortcut += 'ctrl+' ; }
2018-05-02 01:13:42 -05:00
shortcut += obj . key . char . toLowerCase ( ) ;
2018-02-27 05:18:36 -06:00
return shortcut ;
}
2020-04-14 03:02:03 -05:00
export function handleKeyNavigation ( event ) {
let wizardHeader = $ ( event . currentTarget ) . find ( '.wizard-header' ) ;
let wizardFooter = $ ( event . currentTarget ) . find ( '.wizard-footer' ) ;
let gridElement = $ ( event . currentTarget ) . find ( '.select-row-cell:first' ) ;
let gridElementLast = $ ( event . currentTarget ) . find ( '.select-row-cell:last' ) ;
let firstWizardHeaderButton = $ ( wizardHeader ) . find ( 'button:enabled:first' ) ;
let lastWizardHeaderButton = $ ( wizardHeader ) . find ( 'button:enabled:last' ) ;
let lastWizardFooterBtn = $ ( wizardFooter ) . find ( 'button:enabled:last' ) ;
let firstWizardFooterBtn = $ ( wizardFooter ) . find ( 'button:enabled:first' ) ;
if ( event . shiftKey && event . keyCode === 9 ) {
// Move backwards
if ( firstWizardHeaderButton && $ ( firstWizardHeaderButton ) . is ( $ ( event . target ) ) ) {
if ( lastWizardFooterBtn ) {
$ ( lastWizardFooterBtn ) . focus ( ) ;
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
}
}
else if ( $ ( firstWizardFooterBtn ) . is ( $ ( event . target ) ) ) {
if ( $ ( gridElement ) . find ( '.custom-control-input' ) . is ( ':visible' ) ) {
$ ( gridElementLast ) . find ( '.custom-control-input' ) . focus ( ) ;
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
} else if ( $ ( event . currentTarget ) . find ( '.wizard-content' ) . find ( '.CodeMirror-scroll' ) . is ( ':visible' ) ) {
$ ( lastWizardHeaderButton ) . focus ( ) ;
}
}
} else if ( event . keyCode === 9 ) {
// Move forwards
// If taget is last button then goto first element
if ( lastWizardFooterBtn && $ ( lastWizardFooterBtn ) . is ( $ ( event . target ) ) ) {
$ ( firstWizardHeaderButton ) . focus ( ) ;
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
} else if ( event . target . innerText == 'Name' ) {
if ( $ ( gridElement ) . find ( '.custom-control-input' ) . is ( ':visible' ) ) {
$ ( gridElement ) . find ( '.custom-control-input' ) . focus ( ) ;
} else {
$ ( firstWizardFooterBtn ) . focus ( ) ;
}
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
} else if ( event . target . tagName == 'DIV' ) {
$ ( event . currentTarget ) . find ( '.custom-control-input:first' ) . trigger ( 'focus' ) ;
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
} else if ( event . target . tagName == 'TEXTAREA' ) {
$ ( firstWizardFooterBtn ) . focus ( ) ;
}
} else if ( event . keyCode === 27 ) {
//close the wizard when esc key is pressed
$ ( wizardHeader ) . find ( 'button.ajs-close' ) . click ( ) ;
}
}
2018-02-27 05:18:36 -06:00
export function findAndSetFocus ( container ) {
if ( container . length == 0 ) {
return ;
}
setTimeout ( function ( ) {
2022-09-08 07:38:58 -05:00
let first _el = container
2018-02-27 05:18:36 -06:00
. find ( 'button.fa-plus:first' ) ;
2019-05-15 06:07:06 -05:00
/ * A d d i n g t h e t a b i n d e x c o n d i t i o n m a k e s s u r e t h a t
* when testing accessibility it works consistently across all
* browser . For eg , in safari focus ( ) works only when element has
* tabindex = "0" , whereas in Chrome it works in any case
* /
2020-04-06 07:03:07 -05:00
2018-02-27 05:18:36 -06:00
if ( first _el . length == 0 ) {
first _el = container
2019-05-15 06:07:06 -05:00
. find ( `
. pgadmin - controls : first . btn : not ( . toggle ) ,
2020-04-06 07:03:07 -05:00
. pgadmin - controls : first ,
2020-02-25 06:53:36 -06:00
. ajs - commands : first ,
2020-04-07 03:18:56 -05:00
. CodeMirror - scroll ,
. pgadmin - wizard ` )
. find ( '*[tabindex]:not([tabindex="-1"]),input:enabled' ) ;
2018-02-27 05:18:36 -06:00
}
if ( first _el . length > 0 ) {
first _el [ 0 ] . focus ( ) ;
} else {
container [ 0 ] . focus ( ) ;
}
} , 200 ) ;
}
2018-07-25 01:40:46 -05:00
2019-02-04 04:09:47 -06:00
export function getEpoch ( inp _date ) {
let date _obj = inp _date ? inp _date : new Date ( ) ;
return parseInt ( date _obj . getTime ( ) / 1000 ) ;
}
/* Eucladian GCD */
export function getGCD ( inp _arr ) {
let gcd _for _two = ( a , b ) => {
return a == 0 ? b : gcd _for _two ( b % a , a ) ;
} ;
let inp _len = inp _arr . length ;
if ( inp _len <= 2 ) {
return gcd _for _two ( inp _arr [ 0 ] , inp _arr [ 1 ] ) ;
}
let result = inp _arr [ 0 ] ;
for ( let i = 1 ; i < inp _len ; i ++ ) {
result = gcd _for _two ( inp _arr [ i ] , result ) ;
}
return result ;
2019-05-15 06:07:06 -05:00
}
2019-06-10 05:10:49 -05:00
export function getMod ( no , divisor ) {
return ( ( no % divisor ) + divisor ) % divisor ;
}
2019-06-27 09:30:05 -05:00
export function parseFuncParams ( label ) {
let paramArr = [ ] ,
funcName = '' ,
paramStr = '' ;
if ( label . endsWith ( '()' ) ) {
funcName = label . substring ( 0 , label . length - 2 ) ;
} else if ( ! label . endsWith ( ')' ) ) {
funcName = label ;
} else if ( ! label . endsWith ( '()' ) && label . endsWith ( ')' ) ) {
let i = 0 ,
startBracketPos = label . length ;
/* Parse through the characters in reverse to find the param start bracket */
i = label . length - 2 ;
while ( i >= 0 ) {
if ( label [ i ] == '(' ) {
startBracketPos = i ;
break ;
} else if ( label [ i ] == '"' ) {
/* If quotes, skip all the chars till next quote */
i -- ;
while ( label [ i ] != '"' ) i -- ;
}
i -- ;
}
funcName = label . substring ( 0 , startBracketPos ) ;
paramStr = label . substring ( startBracketPos + 1 , label . length - 1 ) ;
let paramStart = 0 ,
paramName = '' ,
paramModes = [ 'IN' , 'OUT' , 'INOUT' , 'VARIADIC' ] ;
2020-06-18 00:44:56 -05:00
i = 0 ;
2019-06-27 09:30:05 -05:00
while ( i < paramStr . length ) {
if ( paramStr [ i ] == '"' ) {
/* If quotes, skip all the chars till next quote */
i ++ ;
while ( paramStr [ i ] != '"' ) i ++ ;
} else if ( paramStr [ i ] == ' ' ) {
/ * i f p a r a m N a m e i s a l r e a d y s e t , i g n o r e t i l l c o m m a
* Or if paramName is parsed as one of the modes , reset .
* /
if ( paramName == '' || paramModes . indexOf ( paramName ) > - 1 ) {
paramName = paramStr . substring ( paramStart , i ) ;
paramStart = i + 1 ;
}
}
else if ( paramStr [ i ] == ',' ) {
paramArr . push ( [ paramName , paramStr . substring ( paramStart , i ) ] ) ;
paramName = '' ;
paramStart = i + 1 ;
}
i ++ ;
}
paramArr . push ( [ paramName , paramStr . substring ( paramStart ) ] ) ;
}
return {
'func_name' : funcName ,
'param_string' : paramStr ,
'params' : paramArr ,
} ;
}
export function quote _ident ( value ) {
/* check if the string is number or not */
let quoteIt = false ;
if ( ! isNaN ( parseInt ( value ) ) ) {
quoteIt = true ;
}
if ( value . search ( /[^a-z0-9_]/g ) > - 1 ) {
/* escape double quotes */
value = value . replace ( /"/g , '""' ) ;
quoteIt = true ;
}
if ( quoteIt ) {
return ` " ${ value } " ` ;
} else {
return value ;
}
}
export function fully _qualify ( pgBrowser , data , item ) {
2021-09-27 06:14:26 -05:00
const parentData = pgBrowser . tree . getTreeNodeHierarchy ( item ) ;
2019-06-27 09:30:05 -05:00
let namespace = '' ;
if ( parentData . schema !== undefined ) {
namespace = quote _ident ( parentData . schema . _label ) ;
}
else if ( parentData . view !== undefined ) {
namespace = quote _ident ( parentData . view . _label ) ;
}
else if ( parentData . catalog !== undefined ) {
namespace = quote _ident ( parentData . catalog . _label ) ;
}
if ( parentData . package !== undefined && data . _type != 'package' ) {
if ( namespace == '' ) {
namespace = quote _ident ( parentData . package . _label ) ;
} else {
namespace += '.' + quote _ident ( parentData . package . _label ) ;
}
}
if ( namespace != '' ) {
return namespace + '.' + quote _ident ( data . _label ) ;
} else {
return quote _ident ( data . _label ) ;
}
}
2019-08-23 06:14:20 -05:00
export function getRandomInt ( min , max ) {
2022-08-13 20:39:45 -05:00
const intArray = new Uint32Array ( 1 ) ;
crypto . getRandomValues ( intArray ) ;
2022-09-08 07:38:58 -05:00
let range = max - min + 1 ;
2022-08-13 20:39:45 -05:00
return min + ( intArray [ 0 ] % range ) ;
2019-08-23 06:14:20 -05:00
}
2019-10-10 01:35:28 -05:00
export function titleize ( i _str ) {
2019-11-11 07:17:43 -06:00
if ( i _str === '' || i _str === null ) return i _str ;
2019-10-10 01:35:28 -05:00
return i _str . split ( ' ' )
. map ( w => w [ 0 ] . toUpperCase ( ) + w . substr ( 1 ) . toLowerCase ( ) )
. join ( ' ' ) ;
}
export function sprintf ( i _str ) {
try {
let replaceArgs = arguments ;
return i _str . split ( '%s' )
. map ( function ( w , i ) {
if ( i > 0 ) {
if ( i < replaceArgs . length ) {
return [ replaceArgs [ i ] , w ] . join ( '' ) ;
} else {
return [ '%s' , w ] . join ( '' ) ;
}
} else {
return w ;
}
} )
. join ( '' ) ;
} catch ( e ) {
console . error ( e ) ;
return i _str ;
}
}
2020-08-10 06:23:32 -05:00
// Modified ref: http://stackoverflow.com/a/1293163/2343 to suite pgAdmin.
// This will parse a delimited string into an array of arrays.
2022-04-07 07:06:56 -05:00
export function CSVToArray ( strData , strDelimiter , quoteChar ) {
2020-08-10 06:23:32 -05:00
strDelimiter = strDelimiter || ',' ;
quoteChar = quoteChar || '"' ;
// Create a regular expression to parse the CSV values.
2022-09-08 07:38:58 -05:00
let objPattern = new RegExp (
2020-08-10 06:23:32 -05:00
(
// Delimiters.
'(\\' + strDelimiter + '|\\r?\\n|\\r|^)' +
// Quoted fields.
( quoteChar == '"' ? '(?:"([^"]*(?:""[^"]*)*)"|' : '(?:\'([^\']*(?:\'\'[^\']*)*)\'|' ) +
// Standard fields.
( quoteChar == '"' ? '([^"\\' + strDelimiter + '\\r\\n]*))' : '([^\'\\' + strDelimiter + '\\r\\n]*))' )
) ,
'gi'
) ;
// Create an array to hold our data. Give the array
// a default empty first row.
2022-09-08 07:38:58 -05:00
let arrData = [ [ ] ] ;
2020-08-10 06:23:32 -05:00
2022-04-07 07:06:56 -05:00
// The regex doesn't handle and skips start value if
// string starts with delimiter
if ( strData . startsWith ( strDelimiter ) ) {
arrData [ arrData . length - 1 ] . push ( null ) ;
}
2020-08-10 06:23:32 -05:00
// Create an array to hold our individual pattern
// matching groups.
2022-09-08 07:38:58 -05:00
let arrMatches = null ;
2020-08-10 06:23:32 -05:00
// Keep looping over the regular expression matches
// until we can no longer find a match.
while ( ( arrMatches = objPattern . exec ( strData ) ) ) {
// Get the delimiter that was found.
2022-09-08 07:38:58 -05:00
let strMatchedDelimiter = arrMatches [ 1 ] ;
2020-08-10 06:23:32 -05:00
// Check to see if the given delimiter has a length
// (is not the start of string) and if it matches
// field delimiter. If id does not, then we know
// that this delimiter is a row delimiter.
if ( strMatchedDelimiter . length && strMatchedDelimiter !== strDelimiter ) {
// Since we have reached a new row of data,
// add an empty row to our data array.
arrData . push ( [ ] ) ;
}
2022-09-08 07:38:58 -05:00
let strMatchedValue ;
2020-08-10 06:23:32 -05:00
// Now that we have our delimiter out of the way,
// let's check to see which kind of value we
// captured (quoted or unquoted).
if ( arrMatches [ 2 ] ) {
// We found a quoted value. When we capture
// this value, unescape any quotes.
strMatchedValue = arrMatches [ 2 ] . replace ( new RegExp ( quoteChar + quoteChar , 'g' ) , quoteChar ) ;
} else {
// We found a non-quoted value.
strMatchedValue = arrMatches [ 3 ] ;
}
// Now that we have our value string, let's add
// it to the data array.
arrData [ arrData . length - 1 ] . push ( strMatchedValue ) ;
}
// Return the parsed data.
return arrData ;
}
2021-06-04 07:25:35 -05:00
2021-12-07 07:22:40 -06:00
export function hasBinariesConfiguration ( pgBrowser , serverInformation ) {
2021-06-04 07:25:35 -05:00
const module = 'paths' ;
let preference _name = 'pg_bin_dir' ;
let msg = gettext ( 'Please configure the PostgreSQL Binary Path in the Preferences dialog.' ) ;
if ( ( serverInformation . type && serverInformation . type === 'ppas' ) ||
serverInformation . server _type === 'ppas' ) {
preference _name = 'ppas_bin_dir' ;
msg = gettext ( 'Please configure the EDB Advanced Server Binary Path in the Preferences dialog.' ) ;
}
const preference = pgBrowser . get _preference ( module , preference _name ) ;
if ( preference ) {
if ( _ . isUndefined ( preference . value ) || ! checkBinaryPathExists ( preference . value , serverInformation . version ) ) {
2021-12-07 07:22:40 -06:00
Notify . alert ( gettext ( 'Configuration required' ) , msg ) ;
2021-06-04 07:25:35 -05:00
return false ;
}
} else {
2021-12-07 07:22:40 -06:00
Notify . alert (
2021-06-04 07:25:35 -05:00
gettext ( 'Preferences Error' ) ,
gettext ( 'Failed to load preference %s of module %s' , preference _name , module )
) ;
return false ;
}
return true ;
}
function checkBinaryPathExists ( binaryPathArray , selectedServerVersion ) {
let foundDefaultPath = false ,
serverSpecificPathExist = false ,
binPathArray = JSON . parse ( binaryPathArray ) ;
_ . each ( binPathArray , function ( binPath ) {
if ( selectedServerVersion >= binPath . version && selectedServerVersion < binPath . next _major _version ) {
if ( ! _ . isUndefined ( binPath . binaryPath ) && ! _ . isNull ( binPath . binaryPath ) && binPath . binaryPath . trim ( ) !== '' )
serverSpecificPathExist = true ;
}
// Check for default path
if ( binPath . isDefault ) {
foundDefaultPath = true ;
}
} ) ;
return ( serverSpecificPathExist | foundDefaultPath ) ;
}
2021-06-25 01:08:02 -05:00
2021-06-29 04:26:38 -05:00
/* If a function, then evaluate */
export function evalFunc ( obj , func , param ) {
if ( _ . isFunction ( func ) ) {
return func . apply ( obj , [ param ] ) ;
}
return func ;
}
2021-06-25 01:08:02 -05:00
export function registerDetachEvent ( panel ) {
panel . on ( wcDocker . EVENT . DETACHED , function ( ) {
$ ( ( this . $container ) [ 0 ] . ownerDocument ) . find ( '.wcIFrameFloating' ) . attr ( {
style : 'z-index: 1200'
} ) ;
} ) ;
panel . on ( wcDocker . EVENT . ORDER _CHANGED , function ( ) {
2022-09-08 07:38:58 -05:00
let docker = this . docker ( this . _panel ) ;
let dockerPos = docker . $container . offset ( ) ;
let pos = this . $container . offset ( ) ;
let width = this . $container . width ( ) ;
let height = this . $container . height ( ) ;
2021-06-25 01:08:02 -05:00
$ ( ( this . $container ) [ 0 ] . ownerDocument ) . find ( '.wcIFrameFloating' ) . css ( 'top' , pos . top - dockerPos . top ) ;
$ ( ( this . $container ) [ 0 ] . ownerDocument ) . find ( '.wcIFrameFloating' ) . css ( 'left' , pos . left - dockerPos . left ) ;
$ ( ( this . $container ) [ 0 ] . ownerDocument ) . find ( '.wcIFrameFloating' ) . css ( 'width' , width ) ;
$ ( ( this . $container ) [ 0 ] . ownerDocument ) . find ( '.wcIFrameFloating' ) . find ( '.wcIFrameFloating' ) . css ( 'height' , height ) ;
2022-01-25 08:40:31 -06:00
$ ( ( this . $container ) [ 0 ] . ownerDocument ) . find ( '.wcIFrameFloating' ) . attr ( {
style : 'z-index: 1200'
} ) ;
2021-06-25 01:08:02 -05:00
} ) ;
}
2022-02-10 23:06:24 -06:00
export function getBrowser ( ) {
2022-09-08 07:38:58 -05:00
let ua = navigator . userAgent , tem , M = ua . match ( /(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i ) || [ ] ;
2022-02-10 23:06:24 -06:00
if ( /trident/i . test ( M [ 1 ] ) ) {
tem = /\brv[ :]+(\d+)/g . exec ( ua ) || [ ] ;
return { name : 'IE' , version : ( tem [ 1 ] || '' ) } ;
}
2022-07-19 04:57:47 -05:00
if ( ua . startsWith ( 'Nwjs' ) ) {
let nwjs = ua . split ( '-' ) [ 0 ] ? . split ( ':' ) ;
return { name : nwjs [ 0 ] , version : nwjs [ 1 ] } ;
}
2022-02-10 23:06:24 -06:00
if ( M [ 1 ] === 'Chrome' ) {
tem = ua . match ( /\bOPR|Edge\/(\d+)/ ) ;
if ( tem != null ) { return { name : tem [ 0 ] , version : tem [ 1 ] } ; }
}
M = M [ 2 ] ? [ M [ 1 ] , M [ 2 ] ] : [ navigator . appName , navigator . appVersion , '-?' ] ;
if ( ( tem = ua . match ( /version\/(\d+)/i ) ) != null ) { M . splice ( 1 , 1 , tem [ 1 ] ) ; }
return {
name : M [ 0 ] ,
version : M [ 1 ] ,
} ;
}
2022-05-23 05:34:21 -05:00
export function checkTrojanSource ( content , isPasteEvent ) {
// Call the hasTrojanSource function of 'anti-trojan-source' package
if ( hasTrojanSource ( { sourceText : content } ) ) {
let msg = gettext ( 'The file opened contains bidirectional Unicode characters which could be interpreted differently than what is displayed. If this is unexpected it is recommended that you review the text in an application that can display hidden Unicode characters before proceeding.' ) ;
if ( isPasteEvent ) {
msg = gettext ( 'The pasted text contains bidirectional Unicode characters which could be interpreted differently than what is displayed. If this is unexpected it is recommended that you review the text in an application that can display hidden Unicode characters before proceeding.' ) ;
}
Notify . alert ( gettext ( 'Trojan Source Warning' ) , msg ) ;
}
}
2022-07-19 04:57:47 -05:00
export function downloadBlob ( blob , fileName ) {
let urlCreator = window . URL || window . webkitURL ,
downloadUrl = urlCreator . createObjectURL ( blob ) ,
link = document . createElement ( 'a' ) ;
document . body . appendChild ( link ) ;
2022-08-05 08:28:03 -05:00
if ( getBrowser ( ) == 'IE' && window . navigator . msSaveBlob ) {
2022-07-19 04:57:47 -05:00
// IE10+ : (has Blob, but not a[download] or URL)
window . navigator . msSaveBlob ( blob , fileName ) ;
} else {
link . setAttribute ( 'href' , downloadUrl ) ;
link . setAttribute ( 'download' , fileName ) ;
link . click ( ) ;
}
document . body . removeChild ( link ) ;
}
2022-08-09 05:12:16 -05:00
export function toPrettySize ( rawSize ) {
try {
let conVal = convert ( rawSize ) . from ( 'B' ) . toBest ( ) ;
conVal . val = Math . round ( conVal . val * 100 ) / 100 ;
return ` ${ conVal . val } ${ conVal . unit } ` ;
}
catch {
return '' ;
}
}
export function compareSizeVals ( val1 , val2 ) {
const parseAndConvert = ( val ) => {
try {
let [ size , unit ] = val . split ( ' ' ) ;
return convert ( size ) . from ( unit . toUpperCase ( ) ) . to ( 'B' ) ;
} catch {
return - 1 ;
}
} ;
val1 = parseAndConvert ( val1 ) ;
val2 = parseAndConvert ( val2 ) ;
if ( val1 > val2 ) return 1 ;
return ( val1 < val2 ? - 1 : 0 ) ;
}
2022-09-08 04:46:48 -05:00
export function calcFontSize ( fontSize ) {
if ( fontSize ) {
fontSize = parseFloat ( ( Math . round ( parseFloat ( fontSize + 'e+2' ) ) + 'e-2' ) ) ;
let rounded = Number ( fontSize ) ;
if ( rounded > 0 ) {
return rounded + 'em' ;
}
}
return '1em' ;
}
export function pgHandleItemError ( xhr , args ) {
2022-09-08 07:38:58 -05:00
let pgBrowser = window . pgAdmin . Browser ;
2022-09-08 04:46:48 -05:00
if ( ! xhr || ! pgBrowser ) {
return ;
}
2022-09-08 07:38:58 -05:00
let contentType = xhr . getResponseHeader ( 'Content-Type' ) ,
2022-09-08 04:46:48 -05:00
jsonResp = contentType &&
contentType . indexOf ( 'application/json' ) == 0 &&
JSON . parse ( xhr . responseText ) ;
if (
jsonResp && (
xhr . status == 503 ? (
jsonResp . info == 'CONNECTION_LOST' &&
'server' in args . info && jsonResp . data . sid >= 0 &&
jsonResp . data . sid == args . info . server . _id
) : (
xhr . status == 428 &&
jsonResp . errormsg &&
jsonResp . errormsg == gettext ( 'Connection to the server has been lost.' )
)
)
) {
if (
args . preHandleConnectionLost &&
typeof ( args . preHandleConnectionLost ) == 'function'
) {
args . preHandleConnectionLost . apply ( this , arguments ) ;
}
// Check the status of the maintenance server connection.
2022-09-08 07:38:58 -05:00
let server = pgBrowser . Nodes [ 'server' ] ,
2022-09-08 04:46:48 -05:00
ctx = {
resp : jsonResp ,
xhr : xhr ,
args : args ,
} ,
reconnectServer = function ( ) {
2022-09-08 07:38:58 -05:00
let ctx _local = this ,
2022-09-08 04:46:48 -05:00
onServerConnect = function ( _sid , _i , _d ) {
// Yay - server is reconnected.
if ( this . args . info . server . _id == _sid ) {
pgBrowser . Events . off (
'pgadmin:server:connected' , onServerConnect
) ;
pgBrowser . Events . off (
'pgadmin:server:connect:cancelled' , onConnectCancel
) ;
// Do we need to connect the disconnected server now?
if (
this . resp . data . database &&
this . resp . data . database != _d . db
) {
// Server is connected now, we will need to inform the
// database to connect it now.
pgBrowser . Events . trigger (
'pgadmin:database:connection:lost' , this . args . item ,
this . resp , true
) ;
}
}
} . bind ( ctx _local ) ,
onConnectCancel = function ( _sid , _item , _data ) {
// User has cancelled the operation in between.
if ( _sid == this . args . info . server . id ) {
pgBrowser . Events . off ( 'pgadmin:server:connected' , onServerConnect ) ;
pgBrowser . Events . off ( 'pgadmin:server:connect:cancelled' , onConnectCancel ) ;
// Connection to the database will also be cancelled
pgBrowser . Events . trigger (
'pgadmin:database:connect:cancelled' , _sid ,
this . resp . data . database || _data . db , _item , _data
) ;
}
} . bind ( ctx _local ) ;
pgBrowser . Events . on ( 'pgadmin:server:connected' , onServerConnect ) ;
pgBrowser . Events . on ( 'pgadmin:server:connect:cancelled' , onConnectCancel ) ;
// Connection to the server has been lost, we need to inform the
// server first to take the action first.
pgBrowser . Events . trigger (
'pgadmin:server:connection:lost' , this . args . item , this . resp
) ;
} . bind ( ctx ) ;
$ . ajax ( {
url : server . generate _url (
null , 'connect' , args . info . server , true , args . info
) ,
dataType : 'json' ,
} )
. done ( function ( res ) {
if ( res . success && 'connected' in res . data ) {
if ( res . data . connected ) {
// Server is connected, but - the connection with the
// particular database has been lost.
pgBrowser . Events . trigger (
'pgadmin:database:connection:lost' , args . item , jsonResp
) ;
return ;
}
}
// Server was not connected, we should first try to connect
// the server.
reconnectServer ( ) ;
} )
. fail ( function ( ) {
reconnectServer ( ) ;
} ) ;
return true ;
} else if ( jsonResp && jsonResp . info == 'CRYPTKEY_MISSING' && xhr . status == 503 ) {
/ * S u p p r e s s t h e e r r o r h e r e a n d h a n d l e i n p g N o t i f i e r w h e r e v e r
* required , as it has callback option
* /
return false ;
}
return false ;
}
2022-10-11 23:37:30 -05:00
export function fullHexColor ( shortHex ) {
if ( shortHex ? . length == 4 ) {
return shortHex . replace ( RegExp ( '#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])' ) , '#$1$1$2$2$3$3' ) . toUpperCase ( ) ;
}
return shortHex ;
}
2022-12-08 07:47:12 -06:00
export function openNewWindow ( toolForm , title ) {
let { name : browser } = getBrowser ( ) ;
if ( browser == 'Nwjs' ) {
let api = getApiInstance ( ) ;
api ( {
url : url _for ( 'tools.initialize' , null ) ,
method : 'GET' ,
} )
. then ( function ( ) {
openWindow ( toolForm , title ) ;
} )
. catch ( function ( error ) {
Notify . error ( gettext ( ` Error in Tool initialize ${ error . response . data } ` ) ) ;
} ) ;
}
else {
openWindow ( toolForm , title ) ;
}
}
function openWindow ( toolForm , title ) {
let newWin = window . open ( '' , '_blank' ) ;
if ( newWin ) {
newWin . document . write ( toolForm ) ;
newWin . document . title = title ;
let pgBrowser = window . pgAdmin . Browser ;
// Send the signal to runtime, so that proper zoom level will be set.
setTimeout ( function ( ) {
pgBrowser . send _signal _to _runtime ( 'Runtime new window opened' ) ;
} , 500 ) ;
} else {
return false ;
}
}