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,
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
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'
|
||||
}
|
||||
]);
|
||||
@ -59,26 +59,16 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
if (data && data.check == false)
|
||||
return true;
|
||||
|
||||
var t = pgBrowser.tree, i = item, d = itemData;
|
||||
// To iterate over tree to check parent node
|
||||
while (i) {
|
||||
// If it is schema then allow user to create collation
|
||||
if (_.indexOf(['schema'], d._type) > -1)
|
||||
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 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
|
||||
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