mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Implemented Synonym node for EPAS
This commit is contained in:
parent
7b72448ec9
commit
5a78dd7ad3
@ -46,7 +46,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
|||||||
name: 'create_package', node: 'schema', module: this,
|
name: 'create_package', node: 'schema', module: this,
|
||||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||||
category: 'create', priority: 4, label: '{{ _('Package...') }}',
|
category: 'create', priority: 4, label: '{{ _('Package...') }}',
|
||||||
icon: 'wcTabIcon icon-package', data: {action: 'create', check: false},
|
icon: 'wcTabIcon icon-package', data: {action: 'create', check: true},
|
||||||
enable: 'canCreate'
|
enable: 'canCreate'
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
@ -59,26 +59,16 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
|||||||
if (data && data.check == false)
|
if (data && data.check == false)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var t = pgBrowser.tree, i = item, d = itemData;
|
var treeData = this.getTreeNodeHierarchy(item),
|
||||||
// To iterate over tree to check parent node
|
server = treeData['server'];
|
||||||
while (i) {
|
|
||||||
// If it is schema then allow user to create collation
|
if (server && server.server_type === 'pg')
|
||||||
if (_.indexOf(['schema'], d._type) > -1)
|
return false;
|
||||||
return true;
|
|
||||||
|
// If it is catalog then don't allow user to create package
|
||||||
|
if (treeData['catalog'] != undefined)
|
||||||
|
return false;
|
||||||
|
|
||||||
if ('coll-package' == d._type) {
|
|
||||||
//Check if we are not child of catalog
|
|
||||||
prev_i = t.hasParent(i) ? t.parent(i) : null;
|
|
||||||
prev_d = prev_i ? t.itemData(prev_i) : null;
|
|
||||||
if( prev_d._type == 'catalog') {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i = t.hasParent(i) ? t.parent(i) : null;
|
|
||||||
d = i ? t.itemData(i) : null;
|
|
||||||
}
|
|
||||||
// by default we want to allow create menu
|
// by default we want to allow create menu
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,634 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
""" Implements Synonym Node """
|
||||||
|
|
||||||
|
import simplejson as json
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
import pgadmin.browser.server_groups.servers.databases as database
|
||||||
|
from flask import render_template, request, jsonify
|
||||||
|
from flask_babel import gettext
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
|
||||||
|
import SchemaChildModule
|
||||||
|
from pgadmin.browser.utils import PGChildNodeView
|
||||||
|
from pgadmin.utils.ajax import make_json_response, \
|
||||||
|
make_response as ajax_response, internal_server_error
|
||||||
|
from pgadmin.utils.ajax import precondition_required
|
||||||
|
from pgadmin.utils.driver import get_driver
|
||||||
|
|
||||||
|
from config import PG_DEFAULT_DRIVER
|
||||||
|
|
||||||
|
|
||||||
|
class SynonymModule(SchemaChildModule):
|
||||||
|
"""
|
||||||
|
class SynonymModule(CollectionNodeModule)
|
||||||
|
|
||||||
|
A module class for Synonym node derived from CollectionNodeModule.
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
-------
|
||||||
|
* __init__(*args, **kwargs)
|
||||||
|
- Method is used to initialize the Synonym and it's base module.
|
||||||
|
|
||||||
|
* get_nodes(gid, sid, did, scid, syid)
|
||||||
|
- Method is used to generate the browser collection node.
|
||||||
|
|
||||||
|
* node_inode()
|
||||||
|
- Method is overridden from its base class to make the node as leaf node.
|
||||||
|
|
||||||
|
* script_load()
|
||||||
|
- Load the module script for schema, when any of the server node is
|
||||||
|
initialized.
|
||||||
|
"""
|
||||||
|
|
||||||
|
NODE_TYPE = 'synonym'
|
||||||
|
COLLECTION_LABEL = gettext("Synonyms")
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Method is used to initialize the SynonymModule and it's base module.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
*args:
|
||||||
|
**kwargs:
|
||||||
|
"""
|
||||||
|
|
||||||
|
super(SynonymModule, self).__init__(*args, **kwargs)
|
||||||
|
self.min_ver = 90100
|
||||||
|
self.max_ver = None
|
||||||
|
self.server_type = ['ppas']
|
||||||
|
|
||||||
|
def get_nodes(self, gid, sid, did, scid):
|
||||||
|
"""
|
||||||
|
Generate the collection node
|
||||||
|
"""
|
||||||
|
yield self.generate_browser_collection_node(scid)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def script_load(self):
|
||||||
|
"""
|
||||||
|
Load the module script for database, when any of the database node is
|
||||||
|
initialized.
|
||||||
|
"""
|
||||||
|
return database.DatabaseModule.NODE_TYPE
|
||||||
|
|
||||||
|
@property
|
||||||
|
def node_inode(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
blueprint = SynonymModule(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class SynonymView(PGChildNodeView):
|
||||||
|
"""
|
||||||
|
This class is responsible for generating routes for Synonym node
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
-------
|
||||||
|
* __init__(**kwargs)
|
||||||
|
- Method is used to initialize the SynonymView and it's base view.
|
||||||
|
|
||||||
|
* check_precondition()
|
||||||
|
- This function will behave as a decorator which will checks
|
||||||
|
database connection before running view, it will also attaches
|
||||||
|
manager,conn & template_path properties to self
|
||||||
|
|
||||||
|
* list()
|
||||||
|
- This function is used to list all the Synonym nodes within that
|
||||||
|
collection.
|
||||||
|
|
||||||
|
* nodes()
|
||||||
|
- This function will used to create all the child node within that
|
||||||
|
collection, Here it will create all the Synonym node.
|
||||||
|
|
||||||
|
* properties(gid, sid, did, scid, syid)
|
||||||
|
- This function will show the properties of the selected Synonym node
|
||||||
|
|
||||||
|
* create(gid, sid, did, scid)
|
||||||
|
- This function will create the new Synonym object
|
||||||
|
|
||||||
|
* update(gid, sid, did, scid, syid)
|
||||||
|
- This function will update the data for the selected Synonym node
|
||||||
|
|
||||||
|
* delete(self, gid, sid, scid, syid):
|
||||||
|
- This function will drop the Synonym object
|
||||||
|
|
||||||
|
* msql(gid, sid, did, scid, syid)
|
||||||
|
- This function is used to return modified SQL for the selected
|
||||||
|
Synonym node
|
||||||
|
|
||||||
|
* get_sql(data, scid, syid)
|
||||||
|
- This function will generate sql from model data
|
||||||
|
|
||||||
|
* sql(gid, sid, did, scid):
|
||||||
|
- This function will generate sql to show it in sql pane for the
|
||||||
|
selected Synonym node.
|
||||||
|
|
||||||
|
* dependency(gid, sid, did, scid):
|
||||||
|
- This function will generate dependency list show it in dependency
|
||||||
|
pane for the selected Synonym node.
|
||||||
|
|
||||||
|
* dependent(gid, sid, did, scid):
|
||||||
|
- This function will generate dependent list to show it in dependent
|
||||||
|
pane for the selected Synonym node.
|
||||||
|
"""
|
||||||
|
|
||||||
|
node_type = blueprint.node_type
|
||||||
|
|
||||||
|
parent_ids = [
|
||||||
|
{'type': 'int', 'id': 'gid'},
|
||||||
|
{'type': 'int', 'id': 'sid'},
|
||||||
|
{'type': 'int', 'id': 'did'},
|
||||||
|
{'type': 'int', 'id': 'scid'}
|
||||||
|
]
|
||||||
|
ids = [
|
||||||
|
{'type': 'string', 'id': 'syid'}
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = dict({
|
||||||
|
'obj': [
|
||||||
|
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||||
|
{'get': 'list', 'post': 'create'}
|
||||||
|
],
|
||||||
|
'delete': [{'delete': 'delete'}],
|
||||||
|
'children': [{'get': 'children'}],
|
||||||
|
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||||
|
'sql': [{'get': 'sql'}],
|
||||||
|
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||||
|
'stats': [{'get': 'statistics'}],
|
||||||
|
'dependency': [{'get': 'dependencies'}],
|
||||||
|
'dependent': [{'get': 'dependents'}],
|
||||||
|
'module.js': [{}, {}, {'get': 'module_js'}],
|
||||||
|
'get_target_objects': [{'get': 'get_target_objects'},
|
||||||
|
{'get': 'get_target_objects'}]
|
||||||
|
})
|
||||||
|
|
||||||
|
def check_precondition(f):
|
||||||
|
"""
|
||||||
|
This function will behave as a decorator which will checks
|
||||||
|
database connection before running view, it will also attaches
|
||||||
|
manager,conn & template_path properties to self
|
||||||
|
"""
|
||||||
|
|
||||||
|
@wraps(f)
|
||||||
|
def wrap(*args, **kwargs):
|
||||||
|
# Here args[0] will hold self & kwargs will hold gid,sid,did
|
||||||
|
self = args[0]
|
||||||
|
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
|
||||||
|
kwargs['sid']
|
||||||
|
)
|
||||||
|
self.conn = self.manager.connection(did=kwargs['did'])
|
||||||
|
# If DB not connected then return error to browser
|
||||||
|
if not self.conn.connected():
|
||||||
|
return precondition_required(
|
||||||
|
gettext(
|
||||||
|
"Connection to the server has been lost!"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# we will set template path for sql scripts
|
||||||
|
self.template_path = 'synonym/sql/9.1_plus'
|
||||||
|
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
|
return wrap
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def list(self, gid, sid, did, scid):
|
||||||
|
"""
|
||||||
|
This function is used to list all the synonym nodes within that collection.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
JSON of available synonym nodes
|
||||||
|
"""
|
||||||
|
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'properties.sql']), scid=scid)
|
||||||
|
status, res = self.conn.execute_dict(SQL)
|
||||||
|
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
return ajax_response(
|
||||||
|
response=res['rows'],
|
||||||
|
status=200
|
||||||
|
)
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def nodes(self, gid, sid, did, scid):
|
||||||
|
"""
|
||||||
|
This function will used to create all the child node within that collection.
|
||||||
|
Here it will create all the synonym node.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
JSON of available synonym child nodes
|
||||||
|
"""
|
||||||
|
|
||||||
|
res = []
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'nodes.sql']), scid=scid)
|
||||||
|
status, rset = self.conn.execute_2darray(SQL)
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=rset)
|
||||||
|
|
||||||
|
for row in rset['rows']:
|
||||||
|
res.append(
|
||||||
|
self.blueprint.generate_browser_node(
|
||||||
|
row['name'],
|
||||||
|
scid,
|
||||||
|
row['name'],
|
||||||
|
icon="icon-synonym"
|
||||||
|
))
|
||||||
|
|
||||||
|
return make_json_response(
|
||||||
|
data=res,
|
||||||
|
status=200
|
||||||
|
)
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def get_target_objects(self, gid, sid, did, scid, syid=None):
|
||||||
|
"""
|
||||||
|
This function will provide list of objects as per user selection.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
scid: Schema ID
|
||||||
|
syid: Synonym ID
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of objects
|
||||||
|
"""
|
||||||
|
res = []
|
||||||
|
data = dict()
|
||||||
|
for k, v in request.args.items():
|
||||||
|
try:
|
||||||
|
data[k] = json.loads(v, encoding='utf-8')
|
||||||
|
except ValueError:
|
||||||
|
data[k] = v
|
||||||
|
|
||||||
|
sql = render_template("/".join([self.template_path,
|
||||||
|
'get_objects.sql']),
|
||||||
|
trgTyp=data['trgTyp'],
|
||||||
|
trgSchema=data['trgSchema'])
|
||||||
|
status, rset = self.conn.execute_dict(sql)
|
||||||
|
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=rset)
|
||||||
|
|
||||||
|
for row in rset['rows']:
|
||||||
|
res.append({'label': row['name'],
|
||||||
|
'value': row['name']})
|
||||||
|
|
||||||
|
return make_json_response(
|
||||||
|
data=res,
|
||||||
|
status=200
|
||||||
|
)
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def properties(self, gid, sid, did, scid, syid):
|
||||||
|
"""
|
||||||
|
This function will show the properties of the selected synonym node.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
scid: Schema ID
|
||||||
|
syid: Synonym ID
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
JSON of selected synonym node
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'properties.sql']),
|
||||||
|
scid=scid, syid=syid)
|
||||||
|
status, res = self.conn.execute_dict(SQL)
|
||||||
|
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
|
||||||
|
return ajax_response(
|
||||||
|
response=res['rows'][0],
|
||||||
|
status=200
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def create(self, gid, sid, did, scid):
|
||||||
|
"""
|
||||||
|
This function will creates new the synonym object
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = request.form if request.form else json.loads(
|
||||||
|
request.data, encoding='utf-8'
|
||||||
|
)
|
||||||
|
|
||||||
|
required_args = [
|
||||||
|
'name', 'targettype', 'synobjschema', 'synobjname'
|
||||||
|
]
|
||||||
|
|
||||||
|
for arg in required_args:
|
||||||
|
if arg not in data:
|
||||||
|
return make_json_response(
|
||||||
|
status=410,
|
||||||
|
success=0,
|
||||||
|
errormsg=gettext(
|
||||||
|
"Could not find the required parameter (%s)." % arg
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'create.sql']),
|
||||||
|
data=data, conn=self.conn, comment=False)
|
||||||
|
status, res = self.conn.execute_scalar(SQL)
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
|
||||||
|
return jsonify(
|
||||||
|
node=self.blueprint.generate_browser_node(
|
||||||
|
data['name'],
|
||||||
|
scid,
|
||||||
|
data['name'],
|
||||||
|
icon="icon-synonym"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def delete(self, gid, sid, did, scid, syid):
|
||||||
|
"""
|
||||||
|
This function will delete existing the synonym object
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
syid: Synonym ID
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Below will decide if it's simple drop or drop with cascade call
|
||||||
|
|
||||||
|
try:
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'properties.sql']),
|
||||||
|
scid=scid, syid=syid)
|
||||||
|
|
||||||
|
status, res = self.conn.execute_dict(SQL)
|
||||||
|
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
|
||||||
|
data = res['rows'][0]
|
||||||
|
|
||||||
|
if data['name'] is None:
|
||||||
|
return make_json_response(
|
||||||
|
success=0,
|
||||||
|
errormsg=gettext(
|
||||||
|
'Error: Object not found.'
|
||||||
|
),
|
||||||
|
info=gettext(
|
||||||
|
'The specified synonym could not be found.\n'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'delete.sql']),
|
||||||
|
data=data,
|
||||||
|
conn=self.conn)
|
||||||
|
status, res = self.conn.execute_scalar(SQL)
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
|
||||||
|
return make_json_response(
|
||||||
|
success=1,
|
||||||
|
info=gettext("Synonym dropped"),
|
||||||
|
data={
|
||||||
|
'id': syid,
|
||||||
|
'scid': scid,
|
||||||
|
'did': did
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def update(self, gid, sid, did, scid, syid):
|
||||||
|
"""
|
||||||
|
This function will updates existing the synonym object
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
syid: Synonym ID
|
||||||
|
"""
|
||||||
|
data = request.form if request.form else json.loads(
|
||||||
|
request.data, encoding='utf-8'
|
||||||
|
)
|
||||||
|
SQL = self.get_sql(gid, sid, data, scid, syid)
|
||||||
|
try:
|
||||||
|
if SQL and SQL.strip('\n') and SQL.strip(' '):
|
||||||
|
status, res = self.conn.execute_scalar(SQL)
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
|
||||||
|
return make_json_response(
|
||||||
|
success=1,
|
||||||
|
info="Synonym updated",
|
||||||
|
data={
|
||||||
|
'id': syid,
|
||||||
|
'scid': scid,
|
||||||
|
'did': did
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return make_json_response(
|
||||||
|
success=1,
|
||||||
|
info="Nothing to update",
|
||||||
|
data={
|
||||||
|
'id': syid,
|
||||||
|
'scid': scid,
|
||||||
|
'did': did
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def msql(self, gid, sid, did, scid, syid=None):
|
||||||
|
"""
|
||||||
|
This function will generates modified sql for synonym object
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
syid: Synonym ID
|
||||||
|
"""
|
||||||
|
data = dict()
|
||||||
|
for k, v in request.args.items():
|
||||||
|
try:
|
||||||
|
data[k] = json.loads(v, encoding='utf-8')
|
||||||
|
except ValueError:
|
||||||
|
data[k] = v
|
||||||
|
|
||||||
|
try:
|
||||||
|
SQL = self.get_sql(gid, sid, data, scid, syid)
|
||||||
|
if SQL and SQL.strip('\n') and SQL.strip(' '):
|
||||||
|
return make_json_response(
|
||||||
|
data=SQL,
|
||||||
|
status=200
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
|
def get_sql(self, gid, sid, data, scid, syid=None):
|
||||||
|
"""
|
||||||
|
This function will genrate sql from model data
|
||||||
|
"""
|
||||||
|
if syid is not None:
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'properties.sql']),
|
||||||
|
scid=scid, syid=syid)
|
||||||
|
status, res = self.conn.execute_dict(SQL)
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
old_data = res['rows'][0]
|
||||||
|
# If target schema/object is not present then take it from
|
||||||
|
# old data, it means it does not changed
|
||||||
|
if 'synobjschema' not in data:
|
||||||
|
data['synobjschema'] = old_data['synobjschema']
|
||||||
|
if 'synobjname' not in data:
|
||||||
|
data['synobjname'] = old_data['synobjname']
|
||||||
|
|
||||||
|
SQL = render_template(
|
||||||
|
"/".join([self.template_path, 'update.sql']),
|
||||||
|
data=data, o_data=old_data, conn=self.conn
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
required_args = [
|
||||||
|
'name', 'targettype', 'synobjschema', 'synobjname'
|
||||||
|
]
|
||||||
|
|
||||||
|
for arg in required_args:
|
||||||
|
if arg not in data:
|
||||||
|
return "-- missing definition"
|
||||||
|
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'create.sql']), comment=False,
|
||||||
|
data=data, conn=self.conn)
|
||||||
|
return SQL.strip('\n')
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def sql(self, gid, sid, did, scid, syid):
|
||||||
|
"""
|
||||||
|
This function will generates reverse engineered sql for synonym object
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
syid: Synonym ID
|
||||||
|
"""
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'properties.sql']),
|
||||||
|
scid=scid, syid=syid)
|
||||||
|
status, res = self.conn.execute_dict(SQL)
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
|
||||||
|
data = res['rows'][0]
|
||||||
|
|
||||||
|
SQL = render_template("/".join([self.template_path,
|
||||||
|
'create.sql']),
|
||||||
|
data=data, conn=self.conn, comment=True)
|
||||||
|
|
||||||
|
return ajax_response(response=SQL)
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def dependents(self, gid, sid, did, scid, syid):
|
||||||
|
"""
|
||||||
|
This function get the dependents and return ajax response
|
||||||
|
for the Synonym node.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
syid: Synonym ID
|
||||||
|
"""
|
||||||
|
dependents_result = self.get_dependents(
|
||||||
|
self.conn, syid, where="WHERE dep.objid=0::oid"
|
||||||
|
)
|
||||||
|
|
||||||
|
return ajax_response(
|
||||||
|
response=dependents_result,
|
||||||
|
status=200
|
||||||
|
)
|
||||||
|
|
||||||
|
@check_precondition
|
||||||
|
def dependencies(self, gid, sid, did, scid, syid):
|
||||||
|
"""
|
||||||
|
This function get the dependencies and return ajax response
|
||||||
|
for the Synonym node.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gid: Server Group ID
|
||||||
|
sid: Server ID
|
||||||
|
did: Database ID
|
||||||
|
scid: Schema ID
|
||||||
|
syid: Synonym ID
|
||||||
|
"""
|
||||||
|
dependencies_result = self.get_dependencies(
|
||||||
|
self.conn, syid, where="WHERE dep.objid=0::oid"
|
||||||
|
)
|
||||||
|
|
||||||
|
return ajax_response(
|
||||||
|
response=dependencies_result,
|
||||||
|
status=200
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
SynonymView.register_node_view(blueprint)
|
Binary file not shown.
After Width: | Height: | Size: 448 B |
Binary file not shown.
After Width: | Height: | Size: 478 B |
@ -0,0 +1,248 @@
|
|||||||
|
define(
|
||||||
|
['jquery', 'underscore', 'underscore.string', 'pgadmin', 'pgadmin.browser', 'alertify', 'pgadmin.browser.collection'],
|
||||||
|
function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||||
|
|
||||||
|
if (!pgBrowser.Nodes['coll-synonym']) {
|
||||||
|
var databases = pgAdmin.Browser.Nodes['coll-synonym'] =
|
||||||
|
pgAdmin.Browser.Collection.extend({
|
||||||
|
node: 'synonym',
|
||||||
|
label: '{{ _('Synonyms') }}',
|
||||||
|
type: 'coll-synonym',
|
||||||
|
columns: ['name', 'owner','is_public_synonym']
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!pgBrowser.Nodes['synonym']) {
|
||||||
|
pgAdmin.Browser.Nodes['synonym'] = pgBrowser.Node.extend({
|
||||||
|
type: 'synonym',
|
||||||
|
dialogHelp: '{{ url_for('help.static', filename='synonym_dialog.html') }}',
|
||||||
|
label: '{{ _('Synonym') }}',
|
||||||
|
collection_type: 'coll-synonym',
|
||||||
|
hasSQL: true,
|
||||||
|
hasDepends: true,
|
||||||
|
parent_type: ['schema', 'catalog'],
|
||||||
|
Init: function() {
|
||||||
|
/* Avoid mulitple registration of menus */
|
||||||
|
if (this.initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.initialized = true;
|
||||||
|
|
||||||
|
pgBrowser.add_menus([{
|
||||||
|
name: 'create_synonym_on_coll', node: 'coll-synonym', module: this,
|
||||||
|
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||||
|
category: 'create', priority: 4, label: '{{ _('Synonym...') }}',
|
||||||
|
icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true},
|
||||||
|
enable: 'canCreate'
|
||||||
|
},{
|
||||||
|
name: 'create_synonym', node: 'synonym', module: this,
|
||||||
|
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||||
|
category: 'create', priority: 4, label: '{{ _('Synonym...') }}',
|
||||||
|
icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true},
|
||||||
|
enable: 'canCreate'
|
||||||
|
},{
|
||||||
|
name: 'create_synonym', node: 'schema', module: this,
|
||||||
|
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||||
|
category: 'create', priority: 4, label: '{{ _('Synonym...') }}',
|
||||||
|
icon: 'wcTabIcon icon-synonym', data: {action: 'create', check: true},
|
||||||
|
enable: 'canCreate'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
},
|
||||||
|
canDrop: pgBrowser.Nodes['schema'].canChildDrop,
|
||||||
|
model: pgAdmin.Browser.Node.Model.extend({
|
||||||
|
isNew: function() {
|
||||||
|
return !this.fetchFromServer;
|
||||||
|
},
|
||||||
|
idAttribute: 'name',
|
||||||
|
// Default values!
|
||||||
|
initialize: function(attrs, args) {
|
||||||
|
var isNew = (_.size(attrs) === 0);
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||||
|
var schemaInfo = args.node_info.schema;
|
||||||
|
this.set({
|
||||||
|
'owner': userInfo.name,
|
||||||
|
'synobjschema': schemaInfo.label,
|
||||||
|
'schema': schemaInfo.label,
|
||||||
|
'targettype': 'r'
|
||||||
|
}, {silent: true});
|
||||||
|
} else {
|
||||||
|
this.fetchFromServer = true;
|
||||||
|
}
|
||||||
|
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
|
},
|
||||||
|
schema: [{
|
||||||
|
id: 'name', label: '{{ _('Name') }}', cell: 'string',
|
||||||
|
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||||
|
disabled: 'inSchemaWithModelCheck'
|
||||||
|
},{
|
||||||
|
id: 'owner', label:'{{ _('Owner') }}', cell: 'string',
|
||||||
|
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||||
|
disabled: true , control: 'node-list-by-name',
|
||||||
|
node: 'role'
|
||||||
|
},{
|
||||||
|
id: 'schema', label:'{{ _('Schema') }}', cell: 'string',
|
||||||
|
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||||
|
disabled: true , control: 'node-list-by-name',
|
||||||
|
node: 'schema'
|
||||||
|
},{
|
||||||
|
type: 'nested', control: 'fieldset', label: '{{ _('Definition') }}',
|
||||||
|
schema:[{
|
||||||
|
id: 'targettype', label:'{{ _('Target Type') }}', cell: 'string',
|
||||||
|
disabled: 'inSchema', group: '{{ _('Definition') }}',
|
||||||
|
select2: { width: "50%", allowClear: false },
|
||||||
|
options: function(obj) {
|
||||||
|
return [
|
||||||
|
{label: "Table", value: "r"},
|
||||||
|
{label: "Sequence", value: "S"},
|
||||||
|
{label: "View", value: "v"},
|
||||||
|
{label: "Function", value: "f"},
|
||||||
|
{label: "Procedure", value: "p"},
|
||||||
|
{label: "Public Synonym", value: "s"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
control: 'select2'
|
||||||
|
},{
|
||||||
|
id: 'synobjschema', label:'{{ _('Target Schema') }}', cell: 'string',
|
||||||
|
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||||
|
group: '{{ _('Definition') }}', deps: ['targettype'],
|
||||||
|
select2: { allowClear: false }, control: 'node-list-by-name',
|
||||||
|
node: 'schema', filter: function(d) {
|
||||||
|
// Exclude PPAS catalogs
|
||||||
|
var exclude_catalogs = ['pg_catalog', 'sys', 'dbo',
|
||||||
|
'pgagent', 'information_schema',
|
||||||
|
'dbms_job_procedure'];
|
||||||
|
return d && _.indexOf(exclude_catalogs, d.label) == -1;
|
||||||
|
},
|
||||||
|
disabled: function(m) {
|
||||||
|
// If tagetType is synonym then disable it
|
||||||
|
if(!m.inSchema.apply(this, [m])) {
|
||||||
|
var is_synonym = (m.get('targettype') == 's');
|
||||||
|
if(is_synonym) {
|
||||||
|
m.set('synobjschema', 'public', {silent: true});
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
id: 'synobjname', label:'{{ _('Target Object') }}', cell: 'string',
|
||||||
|
type: 'text', disabled: 'inSchema', group: '{{ _('Definition') }}',
|
||||||
|
deps: ['targettype', 'synobjschema'],
|
||||||
|
control: 'node-ajax-options',
|
||||||
|
options: function(control) {
|
||||||
|
var trgTyp = control.model.get('targettype');
|
||||||
|
var trgSchema = control.model.get('synobjschema');
|
||||||
|
var res = [];
|
||||||
|
|
||||||
|
var node = control.field.get('schema_node'),
|
||||||
|
_url = node.generate_url.apply(
|
||||||
|
node, [
|
||||||
|
null, 'get_target_objects', control.field.get('node_data'), false,
|
||||||
|
control.field.get('node_info') ]);
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
timeout: 30000,
|
||||||
|
url: _url,
|
||||||
|
cache: false,
|
||||||
|
async: false,
|
||||||
|
data: {"trgTyp" : trgTyp, "trgSchema" : trgSchema},
|
||||||
|
|
||||||
|
// On success return function list from server
|
||||||
|
success: function(result) {
|
||||||
|
res = result.data;
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
// On failure show error appropriate error message to user
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
try {
|
||||||
|
var err = $.parseJSON(xhr.responseText);
|
||||||
|
if (err.success == 0) {
|
||||||
|
alertify.error(err.errormsg);
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},{
|
||||||
|
id: 'is_public_synonym', label:'{{ _('Public Synonym?') }}',
|
||||||
|
disabled: true, type: 'switch', mode: ['properties'], cell: 'switch',
|
||||||
|
options: { onText: 'Yes', offText: 'No', onColor: 'success',
|
||||||
|
offColor: 'primary', size: 'mini'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
validate: function() {
|
||||||
|
var err = {},
|
||||||
|
msg = undefined;
|
||||||
|
this.errorModel.clear();
|
||||||
|
|
||||||
|
if (_.isUndefined(this.get('name'))
|
||||||
|
|| String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
|
||||||
|
msg = '{{ _('Name cannot be empty.') }}';
|
||||||
|
this.errorModel.set('name', msg);
|
||||||
|
} else if (_.isUndefined(this.get('synobjschema'))
|
||||||
|
|| String(this.get('synobjschema')).replace(/^\s+|\s+$/g, '') == '') {
|
||||||
|
msg = '{{ _('Target schema cannot be empty.') }}';
|
||||||
|
this.errorModel.set('synobjschema', msg);
|
||||||
|
} else if (_.isUndefined(this.get('synobjname'))
|
||||||
|
|| String(this.get('synobjname')).replace(/^\s+|\s+$/g, '') == '') {
|
||||||
|
msg = '{{ _('Target object cannot be empty.') }}';
|
||||||
|
this.errorModel.set('synobjname', msg);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
// We will disable everything if we are under catalog node
|
||||||
|
inSchema: function() {
|
||||||
|
if(this.node_info && 'catalog' in this.node_info)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
// We will check if we are under schema node & in 'create' mode
|
||||||
|
inSchemaWithModelCheck: function(m) {
|
||||||
|
if(this.node_info && 'schema' in this.node_info)
|
||||||
|
{
|
||||||
|
// We will disbale control if it's in 'edit' mode
|
||||||
|
if (m.isNew()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
canCreate: function(itemData, item, data) {
|
||||||
|
//If check is false then , we will allow create menu
|
||||||
|
if (data && data.check == false)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var treeData = this.getTreeNodeHierarchy(item),
|
||||||
|
server = treeData['server'];
|
||||||
|
|
||||||
|
if (server && server.server_type === 'pg')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If it is catalog then don't allow user to create synonyms
|
||||||
|
if (treeData['catalog'] != undefined)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// by default we do not want to allow create menu
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return pgBrowser.Nodes['synonym'];
|
||||||
|
});
|
@ -0,0 +1,17 @@
|
|||||||
|
{% set is_public = False %}
|
||||||
|
{% if data.schema == 'public' %}
|
||||||
|
{% set is_public = True %}
|
||||||
|
{% endif %}
|
||||||
|
{% if comment %}
|
||||||
|
-- {% if is_public %}Public{% else %}Private{% endif %} synonym: {{ conn|qtIdent(data.schema, data.name) }};
|
||||||
|
|
||||||
|
-- DROP {% if is_public %}PUBLIC {% endif %}SYNONYM {{ conn|qtIdent(data.schema, data.name) }};
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
CREATE OR REPLACE {% if is_public %}
|
||||||
|
PUBLIC SYNONYM {{ conn|qtIdent(data.name) }}
|
||||||
|
{% else %}
|
||||||
|
SYNONYM {{ conn|qtIdent(data.schema, data.name) }}
|
||||||
|
{% endif %}
|
||||||
|
FOR {{ conn|qtIdent(data.synobjschema, data.synobjname) }};
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
{% set is_public = False %}
|
||||||
|
{% if data.schema == 'public' %}
|
||||||
|
{% set is_public = True %}
|
||||||
|
{% endif %}
|
||||||
|
DROP {% if is_public %}
|
||||||
|
PUBLIC SYNONYM {{ conn|qtIdent(data.name) }}{% else %}
|
||||||
|
SYNONYM {{ conn|qtIdent(data.schema, data.name) }}
|
||||||
|
{% endif %};
|
@ -0,0 +1,43 @@
|
|||||||
|
{###########################################}
|
||||||
|
{### If Target Type is Function ###}
|
||||||
|
{###########################################}
|
||||||
|
{% if trgTyp == 'f' %}
|
||||||
|
SELECT DISTINCT proname AS name
|
||||||
|
FROM pg_proc p, pg_namespace n
|
||||||
|
WHERE p.pronamespace = n.oid AND
|
||||||
|
n.nspname = {{ trgSchema|qtLiteral }} AND
|
||||||
|
p.protype = '0'
|
||||||
|
ORDER BY proname;
|
||||||
|
{###########################################}
|
||||||
|
{### If Target Type is Procedure ###}
|
||||||
|
{###########################################}
|
||||||
|
{% elif trgTyp == 'p' %}
|
||||||
|
SELECT DISTINCT proname AS name
|
||||||
|
FROM pg_proc p, pg_namespace n
|
||||||
|
WHERE p.pronamespace = n.oid AND
|
||||||
|
n.nspname = {{ trgSchema|qtLiteral }} AND
|
||||||
|
p.protype = '1'
|
||||||
|
ORDER BY proname;
|
||||||
|
{###########################################}
|
||||||
|
{### If Target Type is Synonym ###}
|
||||||
|
{###########################################}
|
||||||
|
{% elif trgTyp == 's' %}
|
||||||
|
SELECT synname AS name
|
||||||
|
FROM pg_synonym
|
||||||
|
ORDER BY synname;
|
||||||
|
{% else %}
|
||||||
|
{###################################################}
|
||||||
|
{### If Target Type is Table/View/M.View/Sequnce ###}
|
||||||
|
{###################################################}
|
||||||
|
SELECT relname AS name
|
||||||
|
FROM pg_class c, pg_namespace n
|
||||||
|
WHERE c.relnamespace = n.oid AND
|
||||||
|
n.nspname = {{ trgSchema|qtLiteral }} AND
|
||||||
|
{% if trgTyp == 'v' %}
|
||||||
|
{# If view is select then we need to fetch both view and materialized view #}
|
||||||
|
(c.relkind = 'v' OR c.relkind = 'm')
|
||||||
|
{% else %}
|
||||||
|
c.relkind = {{ trgTyp|qtLiteral }}
|
||||||
|
{% endif %}
|
||||||
|
ORDER BY relname;
|
||||||
|
{% endif %}
|
@ -0,0 +1,8 @@
|
|||||||
|
{# Below will provide oid for newly created collation #}
|
||||||
|
{% if data %}
|
||||||
|
SELECT c.oid
|
||||||
|
FROM pg_collation c, pg_namespace n
|
||||||
|
WHERE c.collnamespace=n.oid AND
|
||||||
|
n.nspname = {{ data.schema|qtLiteral }} AND
|
||||||
|
c.collname = {{ data.name|qtLiteral }}
|
||||||
|
{% endif %}
|
@ -0,0 +1,5 @@
|
|||||||
|
SELECT synname as name
|
||||||
|
FROM pg_synonym s
|
||||||
|
JOIN pg_namespace ns ON s.synnamespace = ns.oid
|
||||||
|
AND s.synnamespace = {{scid}}::oid
|
||||||
|
ORDER BY synname;
|
@ -0,0 +1,19 @@
|
|||||||
|
SELECT synname AS name, pg_get_userbyid(synowner) AS owner,
|
||||||
|
synobjschema, synobjname, ns.nspname as schema,
|
||||||
|
COALESCE((SELECT relkind
|
||||||
|
FROM pg_class c, pg_namespace n
|
||||||
|
WHERE c.relnamespace = n.oid
|
||||||
|
AND n.nspname = synobjschema
|
||||||
|
AND c.relname = synobjname),
|
||||||
|
(SELECT CASE WHEN p.protype = '0' THEN 'f'::"char" ELSE 'p'::"char" END
|
||||||
|
FROM pg_proc p, pg_namespace n
|
||||||
|
WHERE p.pronamespace = n.oid
|
||||||
|
AND n.nspname = synobjschema
|
||||||
|
AND p.proname = synobjname LIMIT 1), 's') AS targettype, -- Default s = Synonym
|
||||||
|
CASE WHEN ns.nspname = 'public' THEN true ELSE false END AS is_public_synonym
|
||||||
|
FROM pg_synonym s JOIN pg_namespace ns ON s.synnamespace = ns.oid
|
||||||
|
WHERE s.synnamespace={{scid}}::oid
|
||||||
|
{% if syid %}
|
||||||
|
AND s.synname={{ syid|qtLiteral }}
|
||||||
|
{% endif %}
|
||||||
|
ORDER BY synname;
|
@ -0,0 +1,10 @@
|
|||||||
|
{% set is_public = False %}
|
||||||
|
{% if o_data.schema == 'public' %}
|
||||||
|
{% set is_public = True %}
|
||||||
|
{% endif %}
|
||||||
|
CREATE OR REPLACE {% if is_public %}
|
||||||
|
PUBLIC SYNONYM {{ conn|qtIdent(o_data.name) }}
|
||||||
|
{% else %}
|
||||||
|
SYNONYM {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||||
|
{% endif %}
|
||||||
|
FOR {{ conn|qtIdent(data.synobjschema, data.synobjname) }};
|
@ -0,0 +1,17 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class SynonymTestGenerator(BaseTestGenerator):
|
||||||
|
|
||||||
|
def generate_tests(self):
|
||||||
|
return
|
||||||
|
|
@ -0,0 +1,74 @@
|
|||||||
|
# #################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
# ##################################################################
|
||||||
|
|
||||||
|
from regression import test_utils as utils
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
database_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from . import utils as synonym_utils
|
||||||
|
|
||||||
|
|
||||||
|
class SynonymAddTestCase(BaseTestGenerator):
|
||||||
|
""" This class will add new synonym under schema node. """
|
||||||
|
|
||||||
|
scenarios = [
|
||||||
|
# Fetching default URL for synonym node.
|
||||||
|
('Default Node URL', dict(url='/browser/synonym/obj/'))
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""
|
||||||
|
This function perform the three tasks
|
||||||
|
1. Add the test server
|
||||||
|
2. Connect to server
|
||||||
|
3. Add the databases
|
||||||
|
4. Add the schemas
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Firstly, add the server
|
||||||
|
server_utils.add_server(cls.tester)
|
||||||
|
# Connect to server
|
||||||
|
cls.server_connect_response, cls.server_group, cls.server_ids = \
|
||||||
|
server_utils.connect_server(cls.tester)
|
||||||
|
if len(cls.server_connect_response) == 0:
|
||||||
|
raise Exception("No Server(s) connected to add the database!!!")
|
||||||
|
# Add database
|
||||||
|
database_utils.add_database(cls.tester, cls.server_connect_response,
|
||||||
|
cls.server_ids)
|
||||||
|
# Add schemas
|
||||||
|
schema_utils.add_schemas(cls.tester)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
""" This function will add synonym under schema node. """
|
||||||
|
|
||||||
|
synonym_utils.add_synonym(
|
||||||
|
self.tester, self.server_connect_response, self.server_ids)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
"""
|
||||||
|
This function deletes the added synonyms, schemas, database,
|
||||||
|
server and the 'parent_id.pkl' file which is created in setup()
|
||||||
|
function.
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
synonym_utils.delete_synonym(cls.tester)
|
||||||
|
schema_utils.delete_schema(cls.tester)
|
||||||
|
database_utils.delete_database(cls.tester)
|
||||||
|
server_utils.delete_server(cls.tester)
|
||||||
|
utils.delete_parent_id_file()
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
# #################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
# ##################################################################
|
||||||
|
|
||||||
|
|
||||||
|
from regression import test_utils as utils
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
database_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from . import utils as synonym_utils
|
||||||
|
|
||||||
|
|
||||||
|
class SynonymDeleteTestCase(BaseTestGenerator):
|
||||||
|
""" This class will delete added synonym under schema node. """
|
||||||
|
|
||||||
|
scenarios = [
|
||||||
|
# Fetching default URL for synonym node.
|
||||||
|
('Fetch synonym Node URL', dict(url='/browser/synonym/obj/'))
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""
|
||||||
|
This function perform the three tasks
|
||||||
|
1. Add the test server
|
||||||
|
2. Connect to server
|
||||||
|
3. Add the databases
|
||||||
|
4. Add the schemas
|
||||||
|
5. Add the synonyms
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Firstly, add the server
|
||||||
|
server_utils.add_server(cls.tester)
|
||||||
|
# Connect to server
|
||||||
|
cls.server_connect_response, cls.server_group, cls.server_ids = \
|
||||||
|
server_utils.connect_server(cls.tester)
|
||||||
|
if len(cls.server_connect_response) == 0:
|
||||||
|
raise Exception("No Server(s) connected to add the database!!!")
|
||||||
|
# Add database
|
||||||
|
database_utils.add_database(cls.tester, cls.server_connect_response,
|
||||||
|
cls.server_ids)
|
||||||
|
# Add schemas
|
||||||
|
schema_utils.add_schemas(cls.tester)
|
||||||
|
# Add synonyms
|
||||||
|
synonym_utils.add_synonym(cls.tester, cls.server_connect_response,
|
||||||
|
cls.server_ids)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
""" This function will delete synonym under schema node. """
|
||||||
|
|
||||||
|
synonym_utils.delete_synonym(self.tester)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
"""
|
||||||
|
This function deletes the added schemas, database,
|
||||||
|
server and the 'parent_id.pkl' file which is created in setup()
|
||||||
|
function.
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
schema_utils.delete_schema(cls.tester)
|
||||||
|
database_utils.delete_database(cls.tester)
|
||||||
|
server_utils.delete_server(cls.tester)
|
||||||
|
utils.delete_parent_id_file()
|
||||||
|
|
@ -0,0 +1,101 @@
|
|||||||
|
# #################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
# ##################################################################
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from regression import test_utils as utils
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
database_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from . import utils as synonym_utils
|
||||||
|
|
||||||
|
|
||||||
|
class SynonymGetTestCase(BaseTestGenerator):
|
||||||
|
""" This class will fetch new synonym under schema node. """
|
||||||
|
|
||||||
|
scenarios = [
|
||||||
|
# Fetching default URL for synonym node.
|
||||||
|
('Fetch synonym Node URL', dict(url='/browser/synonym/obj/'))
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""
|
||||||
|
This function perform the three tasks
|
||||||
|
1. Add the test server
|
||||||
|
2. Connect to server
|
||||||
|
3. Add the databases
|
||||||
|
4. Add the schemas
|
||||||
|
5. Add the synonyms
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Firstly, add the server
|
||||||
|
server_utils.add_server(cls.tester)
|
||||||
|
# Connect to server
|
||||||
|
cls.server_connect_response, cls.server_group, cls.server_ids = \
|
||||||
|
server_utils.connect_server(cls.tester)
|
||||||
|
if len(cls.server_connect_response) == 0:
|
||||||
|
raise Exception("No Server(s) connected to add the database!!!")
|
||||||
|
# Add database
|
||||||
|
database_utils.add_database(cls.tester, cls.server_connect_response,
|
||||||
|
cls.server_ids)
|
||||||
|
# Add schemas
|
||||||
|
schema_utils.add_schemas(cls.tester)
|
||||||
|
# Add synonyms
|
||||||
|
synonym_utils.add_synonym(cls.tester, cls.server_connect_response,
|
||||||
|
cls.server_ids)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
""" This function will fetch synonym under schema node. """
|
||||||
|
|
||||||
|
all_id = utils.get_ids()
|
||||||
|
server_ids = all_id["sid"]
|
||||||
|
db_ids_dict = all_id["did"][0]
|
||||||
|
schema_ids_dict = all_id["scid"][0]
|
||||||
|
synonym_ids_dict = all_id["syid"][0]
|
||||||
|
|
||||||
|
for server_id in server_ids:
|
||||||
|
db_id = db_ids_dict[int(server_id)]
|
||||||
|
db_con = database_utils.verify_database(self.tester,
|
||||||
|
utils.SERVER_GROUP,
|
||||||
|
server_id, db_id)
|
||||||
|
if db_con['data']["connected"]:
|
||||||
|
schema_info = schema_ids_dict[int(server_id)]
|
||||||
|
schema_response = schema_utils.verify_schemas(
|
||||||
|
self.tester, server_id, db_id, schema_info[0])
|
||||||
|
schema_response = json.loads(
|
||||||
|
schema_response.data.decode('utf-8'))
|
||||||
|
if len(schema_response) != 0:
|
||||||
|
synonym_id = synonym_ids_dict[int(server_id)]
|
||||||
|
get_response = synonym_utils.verify_synonym(
|
||||||
|
self.tester, server_id, db_id, schema_info[0],
|
||||||
|
synonym_id)
|
||||||
|
self.assertEquals(get_response.status_code, 200)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
"""
|
||||||
|
This function deletes the added synonyms, schemas, database,
|
||||||
|
server and the 'parent_id.pkl' file which is created in setup()
|
||||||
|
function.
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
synonym_utils.delete_synonym(cls.tester)
|
||||||
|
schema_utils.delete_schema(cls.tester)
|
||||||
|
database_utils.delete_database(cls.tester)
|
||||||
|
server_utils.delete_server(cls.tester)
|
||||||
|
utils.delete_parent_id_file()
|
||||||
|
|
@ -0,0 +1,125 @@
|
|||||||
|
# #################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
# ##################################################################
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from regression import test_utils as utils
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression.test_setup import advanced_config_data
|
||||||
|
from pgadmin.browser.server_groups.servers.tests import utils as server_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
|
database_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from . import utils as synonym_utils
|
||||||
|
|
||||||
|
|
||||||
|
class SynonymPutTestCase(BaseTestGenerator):
|
||||||
|
""" This class will update added synonym under schema node. """
|
||||||
|
|
||||||
|
scenarios = [
|
||||||
|
# Fetching default URL for synonym node.
|
||||||
|
('Fetch synonym Node URL', dict(url='/browser/synonym/obj/'))
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""
|
||||||
|
This function perform the three tasks
|
||||||
|
1. Add the test server
|
||||||
|
2. Connect to server
|
||||||
|
3. Add the databases
|
||||||
|
4. Add the schemas
|
||||||
|
5. Add the synonyms
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Firstly, add the server
|
||||||
|
server_utils.add_server(cls.tester)
|
||||||
|
# Connect to server
|
||||||
|
cls.server_connect_response, cls.server_group, cls.server_ids = \
|
||||||
|
server_utils.connect_server(cls.tester)
|
||||||
|
if len(cls.server_connect_response) == 0:
|
||||||
|
raise Exception("No Server(s) connected to add the database!!!")
|
||||||
|
# Add database
|
||||||
|
database_utils.add_database(cls.tester, cls.server_connect_response,
|
||||||
|
cls.server_ids)
|
||||||
|
# Add schemas
|
||||||
|
schema_utils.add_schemas(cls.tester)
|
||||||
|
# Add synonyms
|
||||||
|
synonym_utils.add_synonym(cls.tester, cls.server_connect_response,
|
||||||
|
cls.server_ids)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
""" This function will update synonym under schema node. """
|
||||||
|
|
||||||
|
all_id = utils.get_ids()
|
||||||
|
server_ids = all_id["sid"]
|
||||||
|
db_ids_dict = all_id["did"][0]
|
||||||
|
schema_ids_dict = all_id["scid"][0]
|
||||||
|
synonym_ids_dict = all_id["syid"][0]
|
||||||
|
|
||||||
|
for server_id in server_ids:
|
||||||
|
db_id = db_ids_dict[int(server_id)]
|
||||||
|
db_con = database_utils.verify_database(self.tester,
|
||||||
|
utils.SERVER_GROUP,
|
||||||
|
server_id, db_id)
|
||||||
|
if db_con['data']["connected"]:
|
||||||
|
schema_info = schema_ids_dict[int(server_id)]
|
||||||
|
schema_response = schema_utils.verify_schemas(self.tester,
|
||||||
|
server_id,
|
||||||
|
db_id,
|
||||||
|
schema_info[0])
|
||||||
|
schema_response = json.loads(
|
||||||
|
schema_response.data.decode('utf-8'))
|
||||||
|
if len(schema_response) != 0:
|
||||||
|
synonym_id = synonym_ids_dict[int(server_id)]
|
||||||
|
get_response = synonym_utils.verify_synonym(
|
||||||
|
self.tester, server_id, db_id, schema_info[0],
|
||||||
|
synonym_id)
|
||||||
|
|
||||||
|
get_response_data = json.loads(
|
||||||
|
get_response.data.decode('utf-8'))
|
||||||
|
if len(get_response_data) == 0:
|
||||||
|
raise Exception("No synonym node to update.")
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"description":
|
||||||
|
advanced_config_data['synonym_update_data']
|
||||||
|
['comment'],
|
||||||
|
"id": synonym_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
put_response = self.tester.put(
|
||||||
|
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||||
|
str(server_id) + '/' +
|
||||||
|
str(db_id) + '/' +
|
||||||
|
str(schema_info[0]) + '/' +
|
||||||
|
str(synonym_id),
|
||||||
|
data=json.dumps(data),
|
||||||
|
follow_redirects=True)
|
||||||
|
|
||||||
|
self.assertEquals(put_response.status_code, 200)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
"""
|
||||||
|
This function deletes the added synonyms, schemas, database,
|
||||||
|
server and the 'parent_id.pkl' file which is created in setup()
|
||||||
|
function.
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
synonym_utils.delete_synonym(cls.tester)
|
||||||
|
schema_utils.delete_schema(cls.tester)
|
||||||
|
database_utils.delete_database(cls.tester)
|
||||||
|
server_utils.delete_server(cls.tester)
|
||||||
|
utils.delete_parent_id_file()
|
@ -0,0 +1,154 @@
|
|||||||
|
# ##########################################################################
|
||||||
|
#
|
||||||
|
# #pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# #Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||||
|
# #This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
# ##########################################################################
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
from regression.test_setup import pickle_path, advanced_config_data
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||||
|
utils as database_utils
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||||
|
utils as schema_utils
|
||||||
|
from regression import test_utils as utils
|
||||||
|
|
||||||
|
SYNONYM_URL = '/browser/synonym/obj/'
|
||||||
|
|
||||||
|
|
||||||
|
def get_synonym_config_data(server_connect_data):
|
||||||
|
"""This function returns the synonym config data"""
|
||||||
|
|
||||||
|
adv_config_data = None
|
||||||
|
data = None
|
||||||
|
db_user = server_connect_data['data']['user']['name']
|
||||||
|
|
||||||
|
# Get the config data of appropriate db user
|
||||||
|
for config_test_data in \
|
||||||
|
advanced_config_data['synonym_credentials']:
|
||||||
|
if db_user == config_test_data['owner']:
|
||||||
|
adv_config_data = config_test_data
|
||||||
|
|
||||||
|
if adv_config_data is not None:
|
||||||
|
data = {
|
||||||
|
"name": adv_config_data['name'],
|
||||||
|
"schema": adv_config_data['schema'],
|
||||||
|
"synobjname": adv_config_data['synobjname'],
|
||||||
|
"synobjschema": adv_config_data['synobjschema'],
|
||||||
|
"targettype": adv_config_data['targettype']
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def write_synonym_id(response_data, server_id):
|
||||||
|
"""
|
||||||
|
This function writes the server and synonym id
|
||||||
|
|
||||||
|
:param response_data: synonym response data
|
||||||
|
:type response_data: dict
|
||||||
|
:param server_id: server id
|
||||||
|
:type server_id: int
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
synonym_id = response_data['node']['_id']
|
||||||
|
pickle_id_dict = utils.get_pickle_id_dict()
|
||||||
|
if os.path.isfile(pickle_path):
|
||||||
|
existing_server_id = open(pickle_path, 'rb')
|
||||||
|
tol_server_id = pickle.load(existing_server_id)
|
||||||
|
pickle_id_dict = tol_server_id
|
||||||
|
if 'syid' in pickle_id_dict:
|
||||||
|
if pickle_id_dict['syid']:
|
||||||
|
# Add the db_id as value in dict
|
||||||
|
pickle_id_dict["syid"][0].update(
|
||||||
|
{int(server_id): synonym_id})
|
||||||
|
else:
|
||||||
|
# Create new dict with server_id and db_id
|
||||||
|
pickle_id_dict["syid"].append(
|
||||||
|
{int(server_id): synonym_id})
|
||||||
|
db_output = open(pickle_path, 'wb')
|
||||||
|
pickle.dump(pickle_id_dict, db_output)
|
||||||
|
db_output.close()
|
||||||
|
|
||||||
|
|
||||||
|
def add_synonym(tester, server_connect_response, server_ids):
|
||||||
|
"""This function add the synonym to schemas"""
|
||||||
|
|
||||||
|
all_id = utils.get_ids()
|
||||||
|
db_ids_dict = all_id["did"][0]
|
||||||
|
schema_ids_dict = all_id["scid"][0]
|
||||||
|
|
||||||
|
for server_connect_response, server_id in zip(server_connect_response,
|
||||||
|
server_ids):
|
||||||
|
db_id = db_ids_dict[int(server_id)]
|
||||||
|
db_con = database_utils.verify_database(tester, utils.SERVER_GROUP,
|
||||||
|
server_id, db_id)
|
||||||
|
if db_con['data']["connected"]:
|
||||||
|
schema_info = schema_ids_dict[int(server_id)]
|
||||||
|
schema_utils.verify_schemas(tester, server_id, db_id,
|
||||||
|
schema_info[0])
|
||||||
|
data = get_synonym_config_data(server_connect_response)
|
||||||
|
data['schema'] = schema_info[1]
|
||||||
|
response = tester.post(
|
||||||
|
SYNONYM_URL + str(utils.SERVER_GROUP) + '/' + str(server_id)
|
||||||
|
+ '/' + str(db_id) + '/' + str(schema_info[0]) + '/',
|
||||||
|
data=json.dumps(data), content_type='html/json')
|
||||||
|
response_data = json.loads(response.data.decode('utf-8'))
|
||||||
|
write_synonym_id(response_data, server_id)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_synonym(tester, server_id, db_id, schema_id, synonym_id):
|
||||||
|
"""This function verifies the synonym using GET API"""
|
||||||
|
|
||||||
|
get_response = tester.get(
|
||||||
|
SYNONYM_URL + str(utils.SERVER_GROUP) + '/' + str(server_id) + '/' +
|
||||||
|
str(db_id) + '/' + str(schema_id) + '/' + str(synonym_id),
|
||||||
|
content_type='html/json')
|
||||||
|
|
||||||
|
return get_response
|
||||||
|
|
||||||
|
|
||||||
|
def delete_synonym(tester):
|
||||||
|
"""This function deletes the synonyms from schema"""
|
||||||
|
|
||||||
|
all_id = utils.get_ids()
|
||||||
|
server_ids = all_id["sid"]
|
||||||
|
db_ids_dict = all_id["did"][0]
|
||||||
|
schema_ids_dict = all_id["scid"][0]
|
||||||
|
synonym_ids_dict = all_id["syid"][0]
|
||||||
|
|
||||||
|
for server_id in server_ids:
|
||||||
|
db_id = db_ids_dict[int(server_id)]
|
||||||
|
db_con = database_utils.verify_database(tester, utils.SERVER_GROUP,
|
||||||
|
server_id, db_id)
|
||||||
|
if db_con['data']["connected"]:
|
||||||
|
schema_info = schema_ids_dict[int(server_id)]
|
||||||
|
schema_response = schema_utils.verify_schemas(tester, server_id,
|
||||||
|
db_id,
|
||||||
|
schema_info[0])
|
||||||
|
schema_response = json.loads(schema_response.data.decode('utf-8'))
|
||||||
|
if len(schema_response) != 0:
|
||||||
|
synonym_id = synonym_ids_dict[int(server_id)]
|
||||||
|
get_response = verify_synonym(
|
||||||
|
tester, server_id, db_id, schema_info[0], synonym_id)
|
||||||
|
|
||||||
|
get_response_data = json.loads(
|
||||||
|
get_response.data.decode('utf-8'))
|
||||||
|
if len(get_response_data) == 0:
|
||||||
|
raise Exception("No synonym node to delete.")
|
||||||
|
|
||||||
|
del_response = tester.delete(
|
||||||
|
SYNONYM_URL + str(utils.SERVER_GROUP) + '/' +
|
||||||
|
str(server_id) + '/' + str(db_id) + '/' +
|
||||||
|
str(schema_info[0]) + '/' + str(synonym_id),
|
||||||
|
follow_redirects=True)
|
||||||
|
|
||||||
|
assert del_response.status_code == 200
|
||||||
|
del_response_data = json.loads(
|
||||||
|
del_response.data.decode('utf-8'))
|
||||||
|
assert del_response_data['success'] == 1
|
Loading…
Reference in New Issue
Block a user