mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Add support for dropping multiple objects at once from the collection Properties panel. Fixes #1513
This commit is contained in:
parent
3359a0de7a
commit
f17979141c
@ -31,11 +31,17 @@ You can use icons in the *Sessions* table to review or control the state of a se
|
||||
.. image:: images/main_properties_table.png
|
||||
:alt: Properties panel
|
||||
|
||||
The *Properties* tab displays information about the object selected. Click the *Edit* icon in the toolbar under the browser tabs to launch the *Properties* dialog for the selected object.
|
||||
The *Properties* tab displays information about the object selected.
|
||||
|
||||
Click the *Delete* icon in the toolbar under the browser tab to delete the selected objects in the Properties panel.
|
||||
|
||||
Click the *Drop Cascade* icon in the toolbar under the browser tab to delete the selected objects and all dependent objects in the Properties panel.
|
||||
|
||||
.. image:: images/main_properties_icons.png
|
||||
:alt: Object editor icon
|
||||
|
||||
Click the *Edit* icon in the toolbar under the browser tabs to launch the *Properties* dialog for the selected object.
|
||||
|
||||
To preserve any changes to the *Properties* dialog, click the *Save* icon; your modifications will be displayed in the updated *Properties* tab.
|
||||
|
||||
.. image:: images/main_properties_edit.png
|
||||
@ -136,4 +142,4 @@ The *Dependents* tab displays a table of objects that depend on the object curre
|
||||
|
||||
Additional tabs open when you access the extended functionality offered by pgAdmin tools (such as the Query tool, Debugger, or SQL editor). Use the close icon (X) located in the upper-right corner of each tab to close the tab when you are finished using the tool. Like permanent tabs, these tabs may be repositioned in the pgAdmin client window.
|
||||
|
||||
By default, each time you open a tool, pgAdmin will open a new browser tab. You can control this behavior by modifying the *Display* node of the *Preferences* dialog for each tool. To open the *Preferences* dialog, select *Preferences* from the *File* menu.
|
||||
By default, each time you open a tool, pgAdmin will open a new browser tab. You can control this behavior by modifying the *Display* node of the *Preferences* dialog for each tool. To open the *Preferences* dialog, select *Preferences* from the *File* menu.
|
||||
|
@ -10,7 +10,7 @@ This release contains a number of features and fixes reported since the release
|
||||
Features
|
||||
********
|
||||
|
||||
|
||||
| `Feature #1513 <https://redmine.postgresql.org/issues/1513>`_ - Add support for dropping multiple objects at once from the collection Properties panel.
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
@ -242,6 +242,36 @@ def register_browser_preferences(self):
|
||||
fields=fields
|
||||
)
|
||||
|
||||
self.preference.register(
|
||||
'keyboard_shortcuts',
|
||||
'grid_menu_drop_multiple',
|
||||
gettext('Delete/Drop multiple objects'),
|
||||
'keyboardshortcut',
|
||||
{
|
||||
'alt': True,
|
||||
'shift': True,
|
||||
'control': False,
|
||||
'key': {'key_code': 77, 'char': 'm'}
|
||||
},
|
||||
category_label=gettext('Keyboard shortcuts'),
|
||||
fields=fields
|
||||
)
|
||||
|
||||
self.preference.register(
|
||||
'keyboard_shortcuts',
|
||||
'grid_menu_drop_cascade_multiple',
|
||||
gettext('Drop Cascade multiple objects'),
|
||||
'keyboardshortcut',
|
||||
{
|
||||
'alt': True,
|
||||
'shift': True,
|
||||
'control': False,
|
||||
'key': {'key_code': 85, 'char': 'u'}
|
||||
},
|
||||
category_label=gettext('Keyboard shortcuts'),
|
||||
fields=fields
|
||||
)
|
||||
|
||||
self.preference.register(
|
||||
'keyboard_shortcuts',
|
||||
'context_menu',
|
||||
|
@ -104,7 +104,7 @@ class DatabaseView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'nodes': [
|
||||
{'get': 'node'},
|
||||
@ -222,6 +222,15 @@ class DatabaseView(PGChildNodeView):
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
for row in res['rows']:
|
||||
if self.manager.db == row['name']:
|
||||
connected = True
|
||||
row['canDrop'] = False
|
||||
else:
|
||||
conn = self.manager.connection(row['name'], did=row['did'])
|
||||
connected = conn.connected()
|
||||
row['canDrop'] = True
|
||||
|
||||
return ajax_response(
|
||||
response=res['rows'],
|
||||
status=200
|
||||
@ -733,44 +742,54 @@ class DatabaseView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition(action="drop")
|
||||
def delete(self, gid, sid, did):
|
||||
def delete(self, gid, sid, did=None):
|
||||
"""Delete the database."""
|
||||
default_conn = self.manager.connection()
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, res = default_conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if res is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified database could not be found.\n'
|
||||
)
|
||||
if did is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [did]}
|
||||
|
||||
status = self.manager.release(did=did)
|
||||
|
||||
for did in data['ids']:
|
||||
default_conn = self.manager.connection()
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
datname=res, conn=self.conn
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
|
||||
status, msg = default_conn.execute_scalar(SQL)
|
||||
status, res = default_conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
# reconnect if database drop failed.
|
||||
conn = self.manager.connection(did=did, auto_reconnect=True)
|
||||
status, errmsg = conn.connect()
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return internal_server_error(errormsg=msg)
|
||||
if res is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified database could not be found.\n'
|
||||
)
|
||||
)
|
||||
else:
|
||||
|
||||
status = self.manager.release(did=did)
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
datname=res, conn=self.conn
|
||||
)
|
||||
|
||||
status, msg = default_conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
# reconnect if database drop failed.
|
||||
conn = self.manager.connection(did=did,
|
||||
auto_reconnect=True)
|
||||
status, errmsg = conn.connect()
|
||||
|
||||
return internal_server_error(errormsg=msg)
|
||||
|
||||
return make_json_response(success=1)
|
||||
|
||||
|
@ -164,12 +164,12 @@ class CastView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{
|
||||
'get': 'children'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
@ -443,7 +443,7 @@ class CastView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, cid):
|
||||
def delete(self, gid, sid, did, cid=None):
|
||||
"""
|
||||
This function will drop the cast object
|
||||
:param cid: cast id
|
||||
@ -459,50 +459,54 @@ class CastView(PGChildNodeView):
|
||||
else:
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Get name for cast from cid
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
cid=cid)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified cast object could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
# drop cast
|
||||
result = res['rows'][0]
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
castsource=result['castsource'],
|
||||
casttarget=result['casttarget'],
|
||||
cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Cast dropped"),
|
||||
data={
|
||||
'id': cid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
if cid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [cid]}
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
for cid in data['ids']:
|
||||
try:
|
||||
# Get name for cast from cid
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
cid=cid)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified cast object could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
# drop cast
|
||||
result = res['rows'][0]
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
castsource=result['castsource'],
|
||||
casttarget=result['casttarget'],
|
||||
cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Cast dropped")
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def msql(self, gid, sid, did, cid=None):
|
||||
|
@ -58,6 +58,7 @@ define('pgadmin.node.cast', [
|
||||
|
||||
// Define the backform model for cast node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined, // Name of the cast
|
||||
encoding: 'UTF8',
|
||||
|
@ -13,6 +13,7 @@
|
||||
{% else %}
|
||||
SELECT
|
||||
ca.oid,
|
||||
ca.oid as id,
|
||||
CASE
|
||||
WHEN {{datlastsysoid}}::OID > ca.oid then True ELSE False
|
||||
END AS syscast,
|
||||
@ -56,4 +57,4 @@
|
||||
ca.oid > {{datlastsysoid}}::OID
|
||||
{% endif %}
|
||||
ORDER BY st.typname, tt.typname
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
@ -0,0 +1,73 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as cast_utils
|
||||
|
||||
|
||||
class CastsMultipleDeleteTestCase(BaseTestGenerator):
|
||||
""" This class will delete the cast node added under database node. """
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
# Fetching default URL for cast node.
|
||||
('Check Cast Node', dict(url='/browser/cast/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(CastsMultipleDeleteTestCase, self).setUp()
|
||||
self.default_db = self.server["db"]
|
||||
self.database_info = parent_node_dict['database'][-1]
|
||||
self.db_name = self.database_info['db_name']
|
||||
self.server["db"] = self.db_name
|
||||
self.source_type = 'money'
|
||||
self.target_type = 'bigint'
|
||||
self.cast_id = cast_utils.create_cast(self.server, self.source_type,
|
||||
self.target_type)
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete added cast."""
|
||||
self.server_id = self.database_info["server_id"]
|
||||
self.db_id = self.database_info['db_id']
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
connection = utils.get_db_connection(self.server['db'],
|
||||
self.server['username'],
|
||||
self.server['db_password'],
|
||||
self.server['host'],
|
||||
self.server['port'],
|
||||
self.server['sslmode'])
|
||||
response = cast_utils.verify_cast(connection, self.source_type,
|
||||
self.target_type)
|
||||
if len(response) == 0:
|
||||
raise Exception("Could not find cast.")
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' + str(self.db_id) +
|
||||
'/',
|
||||
data=json.dumps({'ids': [self.cast_id]}),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function will disconnect test database."""
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
||||
self.server['db'] = self.default_db
|
@ -164,7 +164,7 @@ class EventTriggerView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'children': [{'get': 'children'}],
|
||||
@ -478,7 +478,7 @@ class EventTriggerView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, etid):
|
||||
def delete(self, gid, sid, did, etid=None):
|
||||
"""
|
||||
This function will delete an existing event trigger object.
|
||||
|
||||
@ -497,48 +497,51 @@ class EventTriggerView(PGChildNodeView):
|
||||
cascade = True
|
||||
else:
|
||||
cascade = False
|
||||
|
||||
if etid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [etid]}
|
||||
|
||||
try:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
etid=etid
|
||||
)
|
||||
status, name = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified event trigger could not be found.\n'
|
||||
)
|
||||
for etid in data['ids']:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
etid=etid
|
||||
)
|
||||
status, name = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
name=name, cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified event trigger could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
name=name, cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Event trigger dropped"),
|
||||
data={
|
||||
'id': etid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=gettext("Event trigger dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def msql(self, gid, sid, did, etid=None):
|
||||
|
@ -12,6 +12,8 @@ define('pgadmin.node.event_trigger', [
|
||||
label: gettext('Event Trigger'),
|
||||
type: 'coll-event_trigger',
|
||||
columns: ['name', 'eventowner', 'comment'],
|
||||
canDrop: true,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
@ -55,6 +57,7 @@ define('pgadmin.node.event_trigger', [
|
||||
},
|
||||
// Define the model for event trigger node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
oid: undefined,
|
||||
name: undefined,
|
||||
|
@ -0,0 +1,107 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils import server_utils as server_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression import trigger_funcs_utils
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as event_trigger_utils
|
||||
|
||||
|
||||
class EventTriggerMultipleDeleteTestCase(BaseTestGenerator):
|
||||
""" This class will delete added event trigger under test database. """
|
||||
scenarios = [
|
||||
# Fetching default URL for event trigger node.
|
||||
('Fetch Event Trigger Node URL',
|
||||
dict(url='/browser/event_trigger/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.schema_id = self.schema_data['schema_id']
|
||||
self.extension_name = "postgres_fdw"
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.db_user = self.server["username"]
|
||||
self.func_name = "trigger_func_%s" % str(uuid.uuid4())[1:8]
|
||||
self.trigger_names = ["event_trigger_delete_%s" % (
|
||||
str(uuid.uuid4())[1:8]), "event_trigger_delete_%s" % (
|
||||
str(uuid.uuid4())[1:8])]
|
||||
server_con = server_utils.connect_server(self, self.server_id)
|
||||
if not server_con["info"] == "Server connected.":
|
||||
raise Exception("Could not connect to server to add resource "
|
||||
"groups.")
|
||||
server_version = 0
|
||||
if "type" in server_con["data"]:
|
||||
if server_con["data"]["version"] < 90300:
|
||||
message = "Event triggers are not supported by PG9.2 " \
|
||||
"and PPAS9.2 and below."
|
||||
self.skipTest(message)
|
||||
self.function_info = trigger_funcs_utils.create_trigger_function(
|
||||
self.server, self.db_name, self.schema_name, self.func_name,
|
||||
server_version)
|
||||
self.event_trigger_ids = []
|
||||
self.event_trigger_ids.append(event_trigger_utils.create_event_trigger(
|
||||
self.server, self.db_name, self.schema_name, self.func_name,
|
||||
self.trigger_names[0]))
|
||||
self.event_trigger_ids.append(event_trigger_utils.create_event_trigger(
|
||||
self.server, self.db_name, self.schema_name, self.func_name,
|
||||
self.trigger_names[1]))
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete event trigger under test database. """
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database.")
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema.")
|
||||
func_name = self.function_info[1]
|
||||
func_response = trigger_funcs_utils.verify_trigger_function(
|
||||
self.server,
|
||||
self.db_name,
|
||||
func_name)
|
||||
if not func_response:
|
||||
raise Exception("Could not find the trigger function.")
|
||||
trigger_response = event_trigger_utils.verify_event_trigger(
|
||||
self.server, self.db_name,
|
||||
self.trigger_names[0])
|
||||
if not trigger_response:
|
||||
raise Exception("Could not find event trigger.")
|
||||
trigger_response = event_trigger_utils.verify_event_trigger(
|
||||
self.server, self.db_name,
|
||||
self.trigger_names[1])
|
||||
if not trigger_response:
|
||||
raise Exception("Could not find event trigger.")
|
||||
data = {'ids': self.event_trigger_ids}
|
||||
del_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id),
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json')
|
||||
self.assertEquals(del_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -123,9 +123,9 @@ class ExtensionView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
@ -327,49 +327,53 @@ class ExtensionView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, eid):
|
||||
def delete(self, gid, sid, did, eid=None):
|
||||
"""
|
||||
This function will drop/drop cascade a extension object
|
||||
"""
|
||||
|
||||
if eid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [eid]}
|
||||
|
||||
cascade = True if self.cmd == 'delete' else False
|
||||
|
||||
try:
|
||||
# check if extension with eid exists
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'delete.sql']), eid=eid)
|
||||
status, name = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
for eid in data['ids']:
|
||||
# check if extension with eid exists
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'delete.sql']), eid=eid)
|
||||
status, name = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified extension could not be found.\n'
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified extension could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# drop extension
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'delete.sql']
|
||||
), name=name, cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
# drop extension
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'delete.sql']
|
||||
), name=name, cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Extension dropped"),
|
||||
data={
|
||||
'id': did,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
}
|
||||
info=gettext("Extension dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
|
@ -84,6 +84,7 @@ define('pgadmin.node.extension', [
|
||||
* of the model in schema.
|
||||
*/
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'eid',
|
||||
schema: [
|
||||
{
|
||||
id: 'name', label: gettext('Name'), first_empty: true,
|
||||
|
@ -0,0 +1,74 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as extension_utils
|
||||
|
||||
|
||||
class ExtensionsDeleteMultipleTestCase(BaseTestGenerator):
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
# Fetching default URL for extension node.
|
||||
('Check Extension Node', dict(url='/browser/extension/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
""" This function will create extensions."""
|
||||
super(ExtensionsDeleteMultipleTestCase, self).setUp()
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
|
||||
self.extension_names = ["dblink", "hstore"]
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.extension_ids = []
|
||||
self.extension_ids.append(extension_utils.create_extension(
|
||||
self.server, self.db_name, self.extension_names[0],
|
||||
self.schema_name))
|
||||
self.extension_ids.append(extension_utils.create_extension(
|
||||
self.server, self.db_name, self.extension_names[1],
|
||||
self.schema_name))
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete extensions added test database. """
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
response = extension_utils.verify_extension(self.server, self.db_name,
|
||||
self.extension_names[0])
|
||||
if not response:
|
||||
raise Exception("Could not find extension.")
|
||||
response = extension_utils.verify_extension(self.server, self.db_name,
|
||||
self.extension_names[1])
|
||||
if not response:
|
||||
raise Exception("Could not find extension.")
|
||||
data = {'ids': self.extension_ids}
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' + str(self.db_id),
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database. """
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -186,11 +186,9 @@ class ForeignDataWrapperView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{
|
||||
'delete': 'delete'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -478,7 +476,7 @@ class ForeignDataWrapperView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, fid):
|
||||
def delete(self, gid, sid, did, fid=None):
|
||||
"""
|
||||
This function will delete the selected foreign data wrapper node.
|
||||
|
||||
@ -488,56 +486,59 @@ class ForeignDataWrapperView(PGChildNodeView):
|
||||
did: Database ID
|
||||
fid: foreign data wrapper ID
|
||||
"""
|
||||
if fid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [fid]}
|
||||
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
cascade = True
|
||||
else:
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Get name of foreign data wrapper from fid
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
fid=fid, conn=self.conn
|
||||
)
|
||||
status, name = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
for fid in data['ids']:
|
||||
try:
|
||||
# Get name of foreign data wrapper from fid
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
fid=fid, conn=self.conn
|
||||
)
|
||||
status, name = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified foreign data'
|
||||
' wrapper could not be found.\n'
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified foreign data'
|
||||
' wrapper could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
# drop foreign data wrapper node
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name,
|
||||
cascade=cascade,
|
||||
conn=self.conn)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
# drop foreign data wrapper node
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name,
|
||||
cascade=cascade,
|
||||
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("Foreign Data Wrapper dropped"),
|
||||
data={
|
||||
'id': fid,
|
||||
'did': did,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Foreign Data Wrapper dropped")
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def msql(self, gid, sid, did, fid=None):
|
||||
|
@ -183,11 +183,9 @@ class ForeignServerView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{
|
||||
'delete': 'delete'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -498,7 +496,7 @@ class ForeignServerView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, fid, fsid):
|
||||
def delete(self, gid, sid, did, fid, fsid=None):
|
||||
"""
|
||||
This function will delete the selected foreign server node.
|
||||
|
||||
@ -510,6 +508,13 @@ class ForeignServerView(PGChildNodeView):
|
||||
fsid: foreign server ID
|
||||
"""
|
||||
|
||||
if fsid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [fsid]}
|
||||
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
cascade = True
|
||||
@ -517,43 +522,40 @@ class ForeignServerView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Get name of foreign data wrapper from fid
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
fsid=fsid, conn=self.conn)
|
||||
status, name = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
for fsid in data['ids']:
|
||||
# Get name of foreign data wrapper from fid
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
fsid=fsid, conn=self.conn)
|
||||
status, name = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified foreign server could not be found.\n'
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified foreign server '
|
||||
'could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# drop foreign server
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
name=name, cascade=cascade,
|
||||
conn=self.conn)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
# drop foreign server
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name, cascade=cascade,
|
||||
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("Foreign Server dropped"),
|
||||
data={
|
||||
'id': fsid,
|
||||
'fid': fid,
|
||||
'did': did,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
}
|
||||
info=gettext("Foreign Server dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -92,6 +92,7 @@ define('pgadmin.node.foreign_server', [
|
||||
|
||||
// Defining model for foreign server node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'fsrvid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
fsrvtype: undefined,
|
||||
|
@ -11,8 +11,6 @@ from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.extensions.tests import \
|
||||
utils as extension_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.foreign_data_wrappers.\
|
||||
tests import utils as fdw_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
@ -39,11 +37,9 @@ class ForeignServerDeleteTestCase(BaseTestGenerator):
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.extension_name = "cube"
|
||||
self.fdw_name = "test_fdw_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.fsrv_name = "test_fsrv_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.extension_id = extension_utils.create_extension(
|
||||
self.server, self.db_name, self.extension_name, self.schema_name)
|
||||
|
||||
self.fdw_id = fdw_utils.create_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
self.fsrv_id = fsrv_utils.create_fsrv(self.server, self.db_name,
|
||||
@ -75,8 +71,9 @@ class ForeignServerDeleteTestCase(BaseTestGenerator):
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database and drop added extension
|
||||
and dependant objects."""
|
||||
extension_utils.drop_extension(self.server, self.db_name,
|
||||
self.extension_name)
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
||||
"""This function disconnect the test database and drop
|
||||
added foreign data server and dependant objects."""
|
||||
fdw_utils.delete_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
||||
|
@ -0,0 +1,90 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.foreign_data_wrappers.\
|
||||
tests import utils as fdw_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as fsrv_utils
|
||||
|
||||
|
||||
class ForeignServerDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will add foreign server under FDW node."""
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
# Fetching default URL for foreign server node.
|
||||
('Check FSRV Node', dict(url='/browser/foreign_server/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
""" This function will create extension and foreign data wrapper."""
|
||||
super(ForeignServerDeleteMultipleTestCase, self).setUp()
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.fdw_name = "test_fdw_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.fsrv_names = ["test_fsrv_%s" % (str(uuid.uuid4())[1:8]),
|
||||
"test_fsrv_%s" % (str(uuid.uuid4())[1:8])]
|
||||
|
||||
self.fdw_id = fdw_utils.create_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
self.fsrv_ids = [fsrv_utils.create_fsrv(self.server, self.db_name,
|
||||
self.fsrv_names[0],
|
||||
self.fdw_name),
|
||||
fsrv_utils.create_fsrv(self.server, self.db_name,
|
||||
self.fsrv_names[1],
|
||||
self.fdw_name)]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will fetch foreign server present under test
|
||||
database."""
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
fdw_response = fdw_utils.verify_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
if not fdw_response:
|
||||
raise Exception("Could not find FDW.")
|
||||
fsrv_response = fsrv_utils.verify_fsrv(self.server, self.db_name,
|
||||
self.fsrv_names[0])
|
||||
if not fsrv_response:
|
||||
raise Exception("Could not find FSRV.")
|
||||
fsrv_response = fsrv_utils.verify_fsrv(self.server, self.db_name,
|
||||
self.fsrv_names[1])
|
||||
if not fsrv_response:
|
||||
raise Exception("Could not find FSRV.")
|
||||
data = {'ids': self.fsrv_ids}
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' + str(self.db_id) +
|
||||
'/' + str(self.fdw_id) + "/",
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database and drop added
|
||||
foreign data server and dependant objects."""
|
||||
fdw_utils.delete_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -200,11 +200,9 @@ class UserMappingView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{
|
||||
'delete': 'delete'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -506,7 +504,7 @@ class UserMappingView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, fid, fsid, umid):
|
||||
def delete(self, gid, sid, did, fid, fsid, umid=None):
|
||||
"""
|
||||
This function will delete the selected user mapping node.
|
||||
|
||||
@ -518,6 +516,12 @@ class UserMappingView(PGChildNodeView):
|
||||
fsid: foreign server ID
|
||||
umid: User mapping ID
|
||||
"""
|
||||
if umid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [umid]}
|
||||
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -526,64 +530,59 @@ class UserMappingView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Get name of foreign server from fsid
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
fsid=fsid, conn=self.conn)
|
||||
status, name = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
for umid in data['ids']:
|
||||
# Get name of foreign server from fsid
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
fsid=fsid, conn=self.conn)
|
||||
status, name = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified foreign server could not be found.\n'
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified foreign server '
|
||||
'could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
umid=umid, conn=self.conn)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
umid=umid, conn=self.conn)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'The specified user mapping could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'The specified user mapping could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
data = res['rows'][0]
|
||||
data = res['rows'][0]
|
||||
|
||||
# drop user mapping
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
data=data, name=name, cascade=cascade,
|
||||
conn=self.conn)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
# drop user mapping
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data, name=name, cascade=cascade,
|
||||
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("User Mapping dropped"),
|
||||
data={
|
||||
'id': umid,
|
||||
'fsid': fsid,
|
||||
'fid': fid,
|
||||
'did': did,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
}
|
||||
info=gettext("User Mapping dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
|
@ -96,6 +96,7 @@ define('pgadmin.node.user_mapping', [
|
||||
|
||||
// Defining model for user mapping node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'um_oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
um_options: [],
|
||||
|
@ -41,11 +41,8 @@ class UserMappingDeleteTestCase(BaseTestGenerator):
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.extension_name = "cube"
|
||||
self.fdw_name = "fdw_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.fsrv_name = "fsrv_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.extension_id = extension_utils.create_extension(
|
||||
self.server, self.db_name, self.extension_name, self.schema_name)
|
||||
self.fdw_id = fdw_utils.create_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
self.fsrv_id = fsrv_utils.create_fsrv(self.server, self.db_name,
|
||||
@ -83,8 +80,9 @@ class UserMappingDeleteTestCase(BaseTestGenerator):
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database and drop added extension
|
||||
and dependant objects."""
|
||||
extension_utils.drop_extension(self.server, self.db_name,
|
||||
self.extension_name)
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
||||
"""This function disconnect the test database and drop
|
||||
foreign data wrapper and dependant objects."""
|
||||
fdw_utils.delete_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
||||
|
@ -0,0 +1,91 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.extensions.tests import \
|
||||
utils as extension_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.foreign_data_wrappers. \
|
||||
foreign_servers.tests import utils as fsrv_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.foreign_data_wrappers.\
|
||||
tests import utils as fdw_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as um_utils
|
||||
|
||||
|
||||
class UserMappingDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will delete user mapping under foreign server node."""
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
# Fetching default URL for user mapping node.
|
||||
('Check user mapping Node', dict(url='/browser/user_mapping/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
""" This function will create extension and foreign data wrapper."""
|
||||
super(UserMappingDeleteMultipleTestCase, self).setUp()
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.fdw_name = "fdw_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.fsrv_name = "fsrv_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.fdw_id = fdw_utils.create_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
self.fsrv_id = fsrv_utils.create_fsrv(self.server, self.db_name,
|
||||
self.fsrv_name, self.fdw_name)
|
||||
self.um_id = um_utils.create_user_mapping(self.server, self.db_name,
|
||||
self.fsrv_name)
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete user mapping present under test
|
||||
database. """
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
fdw_response = fdw_utils.verify_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
if not fdw_response:
|
||||
raise Exception("Could not find FDW.")
|
||||
fsrv_response = fsrv_utils.verify_fsrv(self.server, self.db_name,
|
||||
self.fsrv_name)
|
||||
if not fsrv_response:
|
||||
raise Exception("Could not find FSRV.")
|
||||
um_response = um_utils.verify_user_mapping(self.server, self.db_name,
|
||||
self.fsrv_name)
|
||||
if not um_response:
|
||||
raise Exception("Could not find user mapping.")
|
||||
data = {'ids': [self.um_id]}
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' + str(self.db_id) +
|
||||
'/' + str(self.fdw_id) + '/' +
|
||||
str(self.fsrv_id) + "/",
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json')
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database and drop
|
||||
foreign data wrapper and dependant objects."""
|
||||
fdw_utils.delete_fdw(self.server, self.db_name, self.fdw_name)
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
@ -95,6 +95,7 @@ define('pgadmin.node.foreign_data_wrapper', [
|
||||
|
||||
// Defining model for foreign data wrapper node
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'fdwoid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
fdwowner: undefined,
|
||||
|
@ -0,0 +1,76 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as fdw_utils
|
||||
|
||||
|
||||
class FDWDDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will delete foreign data wrappers under test database."""
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [ # Fetching default URL for foreign_data_wrapper node.
|
||||
('Check FDW Node',
|
||||
dict(url='/browser/foreign_data_wrapper/obj/'))]
|
||||
|
||||
def setUp(self):
|
||||
""" This function will create extension and foreign data wrapper."""
|
||||
super(FDWDDeleteMultipleTestCase, self).setUp()
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.fdw_names = ["fdw_{0}".format(str(uuid.uuid4())[1:8]),
|
||||
"fdw_{0}".format(str(uuid.uuid4())[1:8])]
|
||||
self.fdw_ids = [fdw_utils.create_fdw(self.server, self.db_name,
|
||||
self.fdw_names[0]),
|
||||
fdw_utils.create_fdw(self.server, self.db_name,
|
||||
self.fdw_names[1])]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will fetch foreign data wrapper present under test
|
||||
database."""
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
fdw_response = fdw_utils.verify_fdw(self.server, self.db_name,
|
||||
self.fdw_names[0])
|
||||
if not fdw_response:
|
||||
raise Exception("Could not find FDW.")
|
||||
fdw_response = fdw_utils.verify_fdw(self.server, self.db_name,
|
||||
self.fdw_names[1])
|
||||
if not fdw_response:
|
||||
raise Exception("Could not find FDW.")
|
||||
data = {'ids': self.fdw_ids}
|
||||
delete_response = self.tester.delete(self.url +
|
||||
str(utils.SERVER_GROUP) +
|
||||
'/' + str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/',
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json')
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database and drop added extension
|
||||
and dependant objects."""
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
@ -128,6 +128,6 @@ def delete_fdw(server, db_name, fdw_name):
|
||||
server['port'],
|
||||
server['sslmode'])
|
||||
pg_cursor = connection.cursor()
|
||||
pg_cursor.execute("DROP FOREIGN DATA WRAPPER %s" % fdw_name)
|
||||
pg_cursor.execute("DROP FOREIGN DATA WRAPPER %s CASCADE" % fdw_name)
|
||||
connection.commit()
|
||||
connection.close()
|
||||
|
@ -188,7 +188,7 @@ class LanguageView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -198,7 +198,7 @@ class LanguageView(PGChildNodeView):
|
||||
'dependent': [{'get': 'dependents'}],
|
||||
'get_functions': [{}, {'get': 'get_functions'}],
|
||||
'get_templates': [{}, {'get': 'get_templates'}],
|
||||
'delete': [{'delete': 'delete'}]
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}]
|
||||
})
|
||||
|
||||
def _init_(self, **kwargs):
|
||||
@ -490,7 +490,7 @@ class LanguageView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, lid):
|
||||
def delete(self, gid, sid, did, lid=None):
|
||||
"""
|
||||
This function will drop the language object
|
||||
|
||||
@ -500,6 +500,13 @@ class LanguageView(PGChildNodeView):
|
||||
did: Database ID
|
||||
lid: Language ID
|
||||
"""
|
||||
if lid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [lid]}
|
||||
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
cascade = True
|
||||
@ -507,35 +514,30 @@ class LanguageView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Get name for language from lid
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
lid=lid, conn=self.conn
|
||||
)
|
||||
status, lname = self.conn.execute_scalar(sql)
|
||||
for lid in data['ids']:
|
||||
# Get name for language from lid
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
lid=lid, conn=self.conn
|
||||
)
|
||||
status, lname = self.conn.execute_scalar(sql)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=lname)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=lname)
|
||||
|
||||
# drop language
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
lname=lname, cascade=cascade, conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
# drop language
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
lname=lname, cascade=cascade, conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Language dropped"),
|
||||
data={
|
||||
'id': lid,
|
||||
'did': did,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
}
|
||||
info=gettext("Language dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -59,6 +59,7 @@ define('pgadmin.node.language', [
|
||||
|
||||
// Define the model for language node
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
lanowner: undefined,
|
||||
|
@ -0,0 +1,67 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as language_utils
|
||||
|
||||
|
||||
class LanguagesDeleteMultipleTestCase(BaseTestGenerator):
|
||||
scenarios = [
|
||||
('Language delete test case', dict(url='/browser/language/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.server_data = parent_node_dict["database"][-1]
|
||||
self.server_id = self.server_data["server_id"]
|
||||
self.db_id = self.server_data['db_id']
|
||||
self.db_name = self.server_data["db_name"]
|
||||
self.lang_names = ["language_%s" % str(uuid.uuid4())[1:8],
|
||||
"language_%s" % str(uuid.uuid4())[1:8]]
|
||||
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
self.language_ids = [language_utils.create_language(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.lang_names[0]
|
||||
),
|
||||
language_utils.create_language(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.lang_names[1])
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete languages under test database."""
|
||||
data = {'ids': self.language_ids}
|
||||
response = self.tester.delete("{0}{1}/{2}/{3}/".format(
|
||||
self.url, utils.SERVER_GROUP, self.server_id, self.db_id),
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database."""
|
||||
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -214,7 +214,7 @@ class SchemaView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
|
||||
@ -223,7 +223,8 @@ class SchemaView(PGChildNodeView):
|
||||
'stats': [{'get': 'statistics'}],
|
||||
'dependency': [{'get': 'dependencies'}],
|
||||
'dependent': [{'get': 'dependents'}],
|
||||
'delete': [{'delete': 'delete'}]
|
||||
'delete': [{'delete': 'delete'},
|
||||
{'delete': 'delete'}]
|
||||
})
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -645,7 +646,7 @@ It may have been removed by another user.
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid):
|
||||
def delete(self, gid, sid, did, scid=None):
|
||||
"""
|
||||
This function will delete an existing schema object
|
||||
|
||||
@ -656,54 +657,56 @@ It may have been removed by another user.
|
||||
scid: Schema ID
|
||||
"""
|
||||
|
||||
try:
|
||||
# Get name for schema from did
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'sql/get_name.sql']),
|
||||
_=gettext,
|
||||
scid=scid
|
||||
if scid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [scid]}
|
||||
|
||||
status, name = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified schema could not be found.\n'
|
||||
)
|
||||
for scid in data['ids']:
|
||||
try:
|
||||
# Get name for schema from did
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'sql/get_name.sql']),
|
||||
_=gettext,
|
||||
scid=scid
|
||||
)
|
||||
|
||||
# drop schema
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'sql/delete.sql']),
|
||||
_=gettext, name=name, conn=self.conn,
|
||||
cascade=True if self.cmd == 'delete' else False
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
status, name = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Schema dropped"),
|
||||
data={
|
||||
'id': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
)
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified schema could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return internal_server_error(errormsg=str(e))
|
||||
# drop schema
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'sql/delete.sql']),
|
||||
_=gettext, name=name, conn=self.conn,
|
||||
cascade=True if self.cmd == 'delete' else False
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Schema dropped")
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def msql(self, gid, sid, did, scid=None):
|
||||
|
@ -10,6 +10,8 @@ define('pgadmin.node.catalog_object_column', [
|
||||
label: gettext('catalog_object_column'),
|
||||
type: 'coll-catalog_object_column',
|
||||
columns: ['attname', 'attnum', 'cltype', 'description'],
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@ define('pgadmin.node.catalog_object', [
|
||||
label: gettext('Catalog Objects'),
|
||||
type: 'coll-catalog_object',
|
||||
columns: ['name', 'owner', 'description'],
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -161,9 +161,9 @@ class CollationView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -482,7 +482,7 @@ class CollationView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, coid):
|
||||
def delete(self, gid, sid, did, scid, coid=None):
|
||||
"""
|
||||
This function will delete existing the collation object
|
||||
|
||||
@ -493,6 +493,12 @@ class CollationView(PGChildNodeView):
|
||||
scid: Schema ID
|
||||
coid: Collation ID
|
||||
"""
|
||||
if coid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [coid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
@ -502,40 +508,36 @@ class CollationView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'get_name.sql']),
|
||||
scid=scid, coid=coid)
|
||||
status, name = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
for coid in data['ids']:
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'get_name.sql']),
|
||||
scid=scid, coid=coid)
|
||||
status, name = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified collation could not be found.\n'
|
||||
if name is None:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified collation could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name, cascade=cascade,
|
||||
conn=self.conn)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name, cascade=cascade,
|
||||
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("Collation dropped"),
|
||||
data={
|
||||
'id': coid,
|
||||
'scid': scid,
|
||||
'did': did
|
||||
}
|
||||
info=gettext("Collation dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -54,6 +54,7 @@ define('pgadmin.node.collation', [
|
||||
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
|
@ -0,0 +1,80 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as collation_utils
|
||||
|
||||
|
||||
class CollationDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete added collations under schema node. """
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
# Fetching default URL for collation node.
|
||||
('Fetch collation Node URL', dict(url='/browser/collation/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(CollationDeleteMultipleTestCase, self).setUp()
|
||||
self.schema_info = parent_node_dict["schema"][-1]
|
||||
self.schema_name = self.schema_info["schema_name"]
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
coll_names = ["collation_get_%s" % str(uuid.uuid4())[1:8],
|
||||
"collation_get_%s" % str(uuid.uuid4())[1:8]]
|
||||
|
||||
self.collations = [collation_utils.create_collation(self.server,
|
||||
self.schema_name,
|
||||
coll_names[0],
|
||||
self.db_name),
|
||||
collation_utils.create_collation(self.server,
|
||||
self.schema_name,
|
||||
coll_names[1],
|
||||
self.db_name)
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete collations under schema node. """
|
||||
server_id = self.schema_info["server_id"]
|
||||
db_id = self.schema_info["db_id"]
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
server_id,
|
||||
db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database.")
|
||||
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema.")
|
||||
data = {'ids': [self.collations[0][0], self.collations[1][0]]}
|
||||
schema_id = self.schema_info["schema_id"]
|
||||
get_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' + str(
|
||||
server_id) + '/' +
|
||||
str(db_id) + '/' + str(schema_id),
|
||||
content_type='html/json',
|
||||
data=json.dumps(data),
|
||||
follow_redirects=True,
|
||||
)
|
||||
self.assertEquals(get_response.status_code, 200)
|
||||
# Disconnect database to delete it
|
||||
database_utils.disconnect_database(self, server_id, db_id)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
@ -158,9 +158,9 @@ class DomainView(PGChildNodeView, DataTypeReader):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -581,7 +581,7 @@ AND relkind != 'c'))"""
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, doid):
|
||||
def delete(self, gid, sid, did, scid, doid=None):
|
||||
"""
|
||||
Drops the Domain object.
|
||||
|
||||
@ -592,6 +592,12 @@ AND relkind != 'c'))"""
|
||||
scid: Schema Id
|
||||
doid: Domain Id
|
||||
"""
|
||||
if doid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [doid]}
|
||||
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -599,45 +605,39 @@ AND relkind != 'c'))"""
|
||||
else:
|
||||
cascade = False
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
scid=scid, doid=doid)
|
||||
status, res = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for doid in data['ids']:
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
scid=scid, doid=doid)
|
||||
status, res = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified domain could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified domain could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
name = res['rows'][0]['name']
|
||||
basensp = res['rows'][0]['basensp']
|
||||
name = res['rows'][0]['name']
|
||||
basensp = res['rows'][0]['basensp']
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name, basensp=basensp, cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name, basensp=basensp, cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Domain dropped"),
|
||||
data={
|
||||
'id': doid,
|
||||
'scid': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=gettext("Domain dropped")
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
|
@ -167,9 +167,8 @@ class DomainConstraintView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -450,7 +449,7 @@ class DomainConstraintView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, doid, coid):
|
||||
def delete(self, gid, sid, did, scid, doid, coid=None):
|
||||
"""
|
||||
Drops the Domain Constraint object.
|
||||
|
||||
@ -462,45 +461,47 @@ class DomainConstraintView(PGChildNodeView):
|
||||
doid: Domain Id
|
||||
coid: Domain Constraint Id
|
||||
"""
|
||||
if coid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [coid]}
|
||||
|
||||
try:
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
doid=doid, coid=coid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
for coid in data['ids']:
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
doid=doid, coid=coid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified domain constraint could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified domain constraint '
|
||||
'could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
data = res['rows'][0]
|
||||
data = res['rows'][0]
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Domain Constraint dropped"),
|
||||
data={
|
||||
'id': doid,
|
||||
'scid': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=gettext("Domain Constraint dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -13,6 +13,8 @@ define('pgadmin.node.domain_constraints', [
|
||||
label: gettext('Domain Constraints'),
|
||||
type: 'coll-domain_constraints',
|
||||
columns: ['name', 'description'],
|
||||
canDrop: true,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
@ -59,6 +61,7 @@ define('pgadmin.node.domain_constraints', [
|
||||
},
|
||||
canDrop: schemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
|
@ -120,6 +120,7 @@ define('pgadmin.node.domain', [
|
||||
},
|
||||
// Domain Node Model
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
|
@ -23,7 +23,7 @@ class DomainDeleteTestCase(BaseTestGenerator):
|
||||
""" This class will delete new domain under schema node. """
|
||||
scenarios = [
|
||||
# Fetching default URL for domain node.
|
||||
('Fetch domain Node URL', dict(url='/browser/domain/delete/'))
|
||||
('Fetch domain Node URL', dict(url='/browser/domain/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
@ -61,8 +61,12 @@ class DomainDeleteTestCase(BaseTestGenerator):
|
||||
str(db_id) + '/' +
|
||||
str(self.schema_id) + '/' +
|
||||
str(domain_id),
|
||||
content_type='html/json')
|
||||
content_type='html/json',
|
||||
follow_redirects=True
|
||||
)
|
||||
|
||||
self.assertEquals(get_response.status_code, 200)
|
||||
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, server_id, db_id)
|
||||
|
||||
|
@ -0,0 +1,79 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as domain_utils
|
||||
|
||||
|
||||
class DomainDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete new domains under schema node. """
|
||||
scenarios = [
|
||||
# Fetching default URL for domain node.
|
||||
('Fetch domain Node URL', dict(url='/browser/domain/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(DomainDeleteMultipleTestCase, self).setUp()
|
||||
self.database_info = parent_node_dict["database"][-1]
|
||||
self.db_name = self.database_info["db_name"]
|
||||
self.schema_info = parent_node_dict["schema"][-1]
|
||||
self.schema_name = self.schema_info["schema_name"]
|
||||
self.schema_id = self.schema_info["schema_id"]
|
||||
self.domain_names = ["domain_delete_%s" % (str(uuid.uuid4())[1:8]),
|
||||
"domain_delete_%s" % (str(uuid.uuid4())[1:8])]
|
||||
self.domain_infos = [domain_utils.create_domain(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.schema_id,
|
||||
self.domain_names[0]),
|
||||
domain_utils.create_domain(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.schema_id,
|
||||
self.domain_names[1])]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will add domain under schema node. """
|
||||
db_id = self.database_info["db_id"]
|
||||
server_id = self.database_info["server_id"]
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
server_id, db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to get the domain.")
|
||||
db_name = self.database_info["db_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to get the domain.")
|
||||
data = {'ids': [self.domain_infos[0][0], self.domain_infos[1][0]]}
|
||||
url = self.url + str(utils.SERVER_GROUP) + '/' + str(
|
||||
server_id) + '/' + str(db_id) + '/' + str(self.schema_id) + "/"
|
||||
# Call GET API to verify the domain
|
||||
get_response = self.tester.delete(
|
||||
url,
|
||||
content_type='html/json',
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data))
|
||||
|
||||
self.assertEquals(get_response.status_code, 200)
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, server_id, db_id)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
@ -194,9 +194,9 @@ class ForeignTableView(PGChildNodeView, DataTypeReader):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -708,7 +708,7 @@ class ForeignTableView(PGChildNodeView, DataTypeReader):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, foid):
|
||||
def delete(self, gid, sid, did, scid, foid=None):
|
||||
"""
|
||||
Drops the Foreign Table.
|
||||
|
||||
@ -719,6 +719,13 @@ class ForeignTableView(PGChildNodeView, DataTypeReader):
|
||||
scid: Schema Id
|
||||
foid: Foreign Table Id
|
||||
"""
|
||||
if foid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [foid]}
|
||||
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
cascade = True
|
||||
@ -726,47 +733,41 @@ class ForeignTableView(PGChildNodeView, DataTypeReader):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Fetch Name and Schema Name to delete the foreign table.
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']), scid=scid,
|
||||
foid=foid)
|
||||
status, res = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for foid in data['ids']:
|
||||
# Fetch Name and Schema Name to delete the foreign table.
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']), scid=scid,
|
||||
foid=foid)
|
||||
status, res = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified foreign table could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified foreign table could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
name = res['rows'][0]['name']
|
||||
basensp = res['rows'][0]['basensp']
|
||||
name = res['rows'][0]['name']
|
||||
basensp = res['rows'][0]['basensp']
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name,
|
||||
basensp=basensp,
|
||||
cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=name,
|
||||
basensp=basensp,
|
||||
cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Foreign Table dropped"),
|
||||
data={
|
||||
'id': foid,
|
||||
'scid': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=gettext("Foreign Table dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -0,0 +1,99 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.foreign_data_wrappers. \
|
||||
foreign_servers.tests import utils as fsrv_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.foreign_data_wrappers. \
|
||||
tests import utils as fdw_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as ft_utils
|
||||
|
||||
|
||||
class ForeignTableDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""
|
||||
This class will delete foreign table under database node.
|
||||
"""
|
||||
skip_on_database = ['gpdb']
|
||||
|
||||
scenarios = [
|
||||
# Fetching default URL for foreign table node.
|
||||
('Check foreign table Node', dict(url='/browser/foreign_table/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
""" This function will create foreign data wrapper, foreign server
|
||||
and foreign table. """
|
||||
super(ForeignTableDeleteMultipleTestCase, self).setUp()
|
||||
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.schema_id = self.schema_data['schema_id']
|
||||
self.fdw_name = "fdw_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.fsrv_name = "fsrv_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.ft_name = "ft_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.fdw_id = fdw_utils.create_fdw(self.server, self.db_name,
|
||||
self.fdw_name)
|
||||
self.fsrv_id = fsrv_utils.create_fsrv(self.server, self.db_name,
|
||||
self.fsrv_name, self.fdw_name)
|
||||
self.ft_ids = [ft_utils.create_foreign_table(
|
||||
self.server, self.db_name,
|
||||
self.schema_name, self.fsrv_name,
|
||||
"ft_%s" % (str(uuid.uuid4())[1:8])),
|
||||
ft_utils.create_foreign_table(
|
||||
self.server, self.db_name,
|
||||
self.schema_name, self.fsrv_name,
|
||||
"ft_%s" % (str(uuid.uuid4())[1:8]))
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete foreign table under test database."""
|
||||
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
|
||||
fsrv_response = fsrv_utils.verify_fsrv(self.server, self.db_name,
|
||||
self.fsrv_name)
|
||||
|
||||
if not fsrv_response:
|
||||
raise Exception("Could not find Foreign Server.")
|
||||
|
||||
data = {'ids': self.ft_ids}
|
||||
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
content_type='html/json',
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data))
|
||||
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
""" This function disconnect the test database. """
|
||||
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -188,12 +188,12 @@ class FtsConfigurationView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{
|
||||
'get': 'children'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
@ -531,7 +531,7 @@ class FtsConfigurationView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, cfgid):
|
||||
def delete(self, gid, sid, did, scid, cfgid=None):
|
||||
"""
|
||||
This function will drop the FTS Configuration object
|
||||
:param gid: group id
|
||||
@ -540,6 +540,13 @@ class FtsConfigurationView(PGChildNodeView):
|
||||
:param scid: schema id
|
||||
:param cfgid: FTS Configuration id
|
||||
"""
|
||||
if cfgid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [cfgid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -548,49 +555,44 @@ class FtsConfigurationView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Get name for FTS Configuration from cfgid
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'get_name.sql']),
|
||||
cfgid=cfgid
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for cfgid in data['ids']:
|
||||
# Get name for FTS Configuration from cfgid
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'get_name.sql']),
|
||||
cfgid=cfgid
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified FTS configuration could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified FTS configuration '
|
||||
'could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
# Drop FTS Configuration
|
||||
result = res['rows'][0]
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
name=result['name'],
|
||||
schema=result['schema'],
|
||||
cascade=cascade
|
||||
)
|
||||
|
||||
# Drop FTS Configuration
|
||||
result = res['rows'][0]
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
name=result['name'],
|
||||
schema=result['schema'],
|
||||
cascade=cascade
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=_("FTS Configuration dropped"),
|
||||
data={
|
||||
'id': cfgid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did,
|
||||
'scid': scid
|
||||
}
|
||||
info=_("FTS Configuration dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -452,6 +452,7 @@ define('pgadmin.node.fts_configuration', [
|
||||
|
||||
// Defining model for FTS Configuration node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined, // FTS Configuration name
|
||||
owner: undefined, // FTS Configuration owner
|
||||
|
@ -0,0 +1,89 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as fts_configuration_utils
|
||||
|
||||
|
||||
class FTSConfDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete added FTS configurations under schema node. """
|
||||
|
||||
scenarios = [
|
||||
# Fetching default URL for fts_configuration node.
|
||||
('Fetch FTS configuration Node URL',
|
||||
dict(url='/browser/fts_configuration/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
""" This function will create FTS configuration."""
|
||||
|
||||
schema_data = parent_node_dict['schema'][-1]
|
||||
self.schema_name = schema_data['schema_name']
|
||||
self.schema_id = schema_data['schema_id']
|
||||
self.server_id = schema_data['server_id']
|
||||
self.db_id = schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
|
||||
self.fts_conf_ids = [fts_configuration_utils.create_fts_configuration(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
"fts_conf_%s" % str(uuid.uuid4())[1:8]),
|
||||
fts_configuration_utils.create_fts_configuration(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
"fts_conf_%s" % str(uuid.uuid4())[1:8])
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete the FTS configurations under test
|
||||
schema. """
|
||||
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema.")
|
||||
|
||||
data = {'ids': self.fts_conf_ids}
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json')
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database."""
|
||||
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
@ -180,12 +180,12 @@ class FtsDictionaryView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{
|
||||
'get': 'children'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
@ -526,7 +526,7 @@ class FtsDictionaryView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, dcid):
|
||||
def delete(self, gid, sid, did, scid, dcid=None):
|
||||
"""
|
||||
This function will drop the FTS Dictionary object
|
||||
:param gid: group id
|
||||
@ -535,6 +535,13 @@ class FtsDictionaryView(PGChildNodeView):
|
||||
:param scid: schema id
|
||||
:param dcid: FTS Dictionary id
|
||||
"""
|
||||
if dcid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [dcid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -543,46 +550,43 @@ class FtsDictionaryView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Get name for FTS Dictionary from dcid
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
dcid=dcid)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for dcid in data['ids']:
|
||||
# Get name for FTS Dictionary from dcid
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
dcid=dcid)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified FTS dictionary could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified FTS dictionary '
|
||||
'could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# Drop FTS Dictionary
|
||||
result = res['rows'][0]
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
name=result['name'],
|
||||
schema=result['schema'],
|
||||
cascade=cascade
|
||||
)
|
||||
# Drop FTS Dictionary
|
||||
result = res['rows'][0]
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
name=result['name'],
|
||||
schema=result['schema'],
|
||||
cascade=cascade
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=_("FTS Dictionary dropped"),
|
||||
data={
|
||||
'id': dcid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did,
|
||||
'scid': scid
|
||||
}
|
||||
info=_("FTS Dictionary dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -97,6 +97,7 @@ define('pgadmin.node.fts_dictionary', [
|
||||
|
||||
// Defining backform model for FTS Dictionary node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined, // FTS Dictionary name
|
||||
owner: undefined, // FTS Dictionary owner
|
||||
|
@ -0,0 +1,104 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as fts_dict_utils
|
||||
|
||||
|
||||
class FtsDictionaryDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete the added FTS Dictionary under schema node. """
|
||||
|
||||
scenarios = [
|
||||
# Fetching default URL for FTS dictionary node.
|
||||
('Fetch FTS dictionary Node URL', dict(
|
||||
url='/browser/fts_dictionary/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.schema_id = self.schema_data['schema_id']
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.fts_dict_name = "fts_dict_%s" % str(uuid.uuid4())[1:8]
|
||||
self.fts_dict_name_1 = "fts_dict_%s" % str(uuid.uuid4())[1:8]
|
||||
|
||||
self.fts_dict_ids = [fts_dict_utils.create_fts_dictionary(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.fts_dict_name),
|
||||
fts_dict_utils.create_fts_dictionary(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.fts_dict_name_1),
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will update FTS dictionary present under
|
||||
test schema. """
|
||||
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema.")
|
||||
|
||||
dict_response = fts_dict_utils.verify_fts_dict(self.server,
|
||||
self.db_name,
|
||||
self.fts_dict_name)
|
||||
|
||||
if not dict_response:
|
||||
raise Exception("Could not find the FTS dictionary.")
|
||||
|
||||
dict_response = fts_dict_utils.verify_fts_dict(self.server,
|
||||
self.db_name,
|
||||
self.fts_dict_name_1)
|
||||
|
||||
if not dict_response:
|
||||
raise Exception("Could not find the FTS dictionary.")
|
||||
|
||||
data = {'ids': self.fts_dict_ids}
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database."""
|
||||
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
@ -182,12 +182,12 @@ class FtsParserView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{
|
||||
'get': 'children'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
@ -453,7 +453,7 @@ class FtsParserView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, pid):
|
||||
def delete(self, gid, sid, did, scid, pid=None):
|
||||
"""
|
||||
This function will drop the fts_parser object
|
||||
:param gid: group id
|
||||
@ -462,6 +462,13 @@ class FtsParserView(PGChildNodeView):
|
||||
:param scid: schema id
|
||||
:param pid: fts tempate id
|
||||
"""
|
||||
if pid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [pid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -470,49 +477,43 @@ class FtsParserView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Get name for Parser from pid
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
pid=pid
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for pid in data['ids']:
|
||||
# Get name for Parser from pid
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
pid=pid
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified FTS parser could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified FTS parser could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
# Drop fts Parser
|
||||
result = res['rows'][0]
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
name=result['name'],
|
||||
schema=result['schema'],
|
||||
cascade=cascade
|
||||
)
|
||||
|
||||
# Drop fts Parser
|
||||
result = res['rows'][0]
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
name=result['name'],
|
||||
schema=result['schema'],
|
||||
cascade=cascade
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=_("FTS Parser dropped"),
|
||||
data={
|
||||
'id': pid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did,
|
||||
'scid': scid
|
||||
}
|
||||
info=_("FTS Parser dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -58,6 +58,7 @@ define('pgadmin.node.fts_parser', [
|
||||
|
||||
// Defining backform model for fts parser node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined, // Fts parser name
|
||||
description: undefined, // Comment on parser
|
||||
|
@ -0,0 +1,104 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as fts_parser_utils
|
||||
|
||||
|
||||
class FtsParserDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete added FTS Parser under schema node. """
|
||||
|
||||
scenarios = [
|
||||
# Fetching default URL for FTS parser node.
|
||||
('Fetch FTS parser Node URL', dict(url='/browser/fts_parser/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.schema_id = self.schema_data['schema_id']
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.fts_parser_name = "fts_parser_%s" % str(uuid.uuid4())[1:8]
|
||||
self.fts_parser_name_1 = "fts_parser_%s" % str(uuid.uuid4())[1:8]
|
||||
|
||||
self.fts_parser_ids = [fts_parser_utils.create_fts_parser(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.fts_parser_name),
|
||||
fts_parser_utils.create_fts_parser(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.fts_parser_name_1)
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete FTS parser present under test schema. """
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema.")
|
||||
|
||||
parser_response = fts_parser_utils.verify_fts_parser(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.fts_parser_name)
|
||||
|
||||
if not parser_response:
|
||||
raise Exception("Could not find the FTS parser.")
|
||||
|
||||
parser_response = fts_parser_utils.verify_fts_parser(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.fts_parser_name_1)
|
||||
|
||||
if not parser_response:
|
||||
raise Exception("Could not find the FTS parser.")
|
||||
|
||||
data = {'ids': self.fts_parser_ids}
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database."""
|
||||
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
@ -175,12 +175,12 @@ class FtsTemplateView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{
|
||||
'get': 'children'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
@ -433,7 +433,7 @@ class FtsTemplateView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid):
|
||||
def delete(self, gid, sid, did, scid, tid=None):
|
||||
"""
|
||||
This function will drop the fts_template object
|
||||
:param gid: group id
|
||||
@ -442,6 +442,13 @@ class FtsTemplateView(PGChildNodeView):
|
||||
:param scid: schema id
|
||||
:param tid: fts tempate id
|
||||
"""
|
||||
if tid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [tid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -449,46 +456,40 @@ class FtsTemplateView(PGChildNodeView):
|
||||
else:
|
||||
cascade = False
|
||||
|
||||
# Get name for template from tid
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
tid=tid)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for tid in data['ids']:
|
||||
# Get name for template from tid
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
tid=tid)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified FTS template could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified FTS template could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# Drop fts template
|
||||
result = res['rows'][0]
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
name=result['name'],
|
||||
schema=result['schema'],
|
||||
cascade=cascade
|
||||
)
|
||||
# Drop fts template
|
||||
result = res['rows'][0]
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
name=result['name'],
|
||||
schema=result['schema'],
|
||||
cascade=cascade
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("FTS Template dropped"),
|
||||
data={
|
||||
'id': tid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did,
|
||||
'scid': scid
|
||||
}
|
||||
info=gettext("FTS Template dropped")
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
|
@ -58,6 +58,7 @@ define('pgadmin.node.fts_template', [
|
||||
|
||||
// Defining backform model for fts template node
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined, // Fts template name
|
||||
description: undefined, // Comment on template
|
||||
|
@ -0,0 +1,102 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import \
|
||||
utils as database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as fts_temp_utils
|
||||
|
||||
|
||||
class FtsTemplateDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete new FTS template under schema node. """
|
||||
|
||||
scenarios = [
|
||||
# Fetching default URL for FTS template node.
|
||||
('Fetch FTS template Node URL', dict(url='/browser/fts_template/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.schema_data = parent_node_dict['schema'][-1]
|
||||
self.schema_name = self.schema_data['schema_name']
|
||||
self.schema_id = self.schema_data['schema_id']
|
||||
self.server_id = self.schema_data['server_id']
|
||||
self.db_id = self.schema_data['db_id']
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.fts_temp_name = "fts_temp_%s" % str(uuid.uuid4())[1:8]
|
||||
self.fts_temp_name_1 = "fts_temp_%s" % str(uuid.uuid4())[1:8]
|
||||
self.fts_temp_ids = [fts_temp_utils.create_fts_template(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.fts_temp_name),
|
||||
fts_temp_utils.create_fts_template(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.fts_temp_name_1)
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete FTS template present under
|
||||
test schema. """
|
||||
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema.")
|
||||
|
||||
fts_response = fts_temp_utils.verify_fts_template(self.server,
|
||||
self.db_name,
|
||||
self.fts_temp_name)
|
||||
|
||||
if not fts_response:
|
||||
raise Exception("Could not find the FTS template.")
|
||||
|
||||
fts_response = fts_temp_utils.verify_fts_template(self.server,
|
||||
self.db_name,
|
||||
self.fts_temp_name_1)
|
||||
|
||||
if not fts_response:
|
||||
raise Exception("Could not find the FTS template.")
|
||||
|
||||
data = {'ids': self.fts_temp_ids}
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database."""
|
||||
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
@ -199,9 +199,9 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -801,7 +801,7 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, fnid):
|
||||
def delete(self, gid, sid, did, scid, fnid=None):
|
||||
"""
|
||||
Drop the Function.
|
||||
|
||||
@ -812,6 +812,12 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
scid: Schema Id
|
||||
fnid: Function Id
|
||||
"""
|
||||
if fnid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [fnid]}
|
||||
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -820,45 +826,39 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# Fetch Name and Schema Name to delete the Function.
|
||||
SQL = render_template("/".join([self.sql_template_path,
|
||||
'delete.sql']), scid=scid,
|
||||
fnid=fnid)
|
||||
status, res = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for fnid in data['ids']:
|
||||
# Fetch Name and Schema Name to delete the Function.
|
||||
SQL = render_template("/".join([self.sql_template_path,
|
||||
'delete.sql']), scid=scid,
|
||||
fnid=fnid)
|
||||
status, res = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified function could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified function could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
SQL = render_template("/".join([self.sql_template_path,
|
||||
'delete.sql']),
|
||||
name=res['rows'][0]['name'],
|
||||
func_args=res['rows'][0]['func_args'],
|
||||
nspname=res['rows'][0]['nspname'],
|
||||
cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
SQL = render_template("/".join([self.sql_template_path,
|
||||
'delete.sql']),
|
||||
name=res['rows'][0]['name'],
|
||||
func_args=res['rows'][0]['func_args'],
|
||||
nspname=res['rows'][0]['nspname'],
|
||||
cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Function dropped."),
|
||||
data={
|
||||
'id': fnid,
|
||||
'scid': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=gettext("Function dropped.")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -60,6 +60,7 @@ define('pgadmin.node.trigger_function', [
|
||||
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
if (isNew) {
|
||||
|
@ -0,0 +1,56 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as funcs_utils
|
||||
|
||||
|
||||
class FunctionDeleteTestCase(BaseTestGenerator):
|
||||
""" This class will delete the function under schema node. """
|
||||
scenarios = [
|
||||
# Fetching default URL for function node.
|
||||
('Fetch Function Node URL',
|
||||
dict(url='/browser/function/obj/'))
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete function under database node. """
|
||||
super(FunctionDeleteTestCase, self).setUp()
|
||||
self = funcs_utils.set_up(self)
|
||||
|
||||
func_name = "test_function_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
function_info = funcs_utils.create_function(
|
||||
self.server, self.db_name, self.schema_name, func_name)
|
||||
|
||||
func_name_1 = "test_function_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
function_info_1 = funcs_utils.create_function(
|
||||
self.server, self.db_name, self.schema_name, func_name_1)
|
||||
|
||||
data = {'ids': [function_info[0], function_info_1[0]]}
|
||||
response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
follow_redirects=True,
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
@ -0,0 +1,64 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as funcs_utils
|
||||
|
||||
|
||||
class procedureDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete the procedure under schema node. """
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
# Fetching default URL for procedure node.
|
||||
('Fetch Procedure Node URL',
|
||||
dict(url='/browser/procedure/obj/'))
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete procedure under database node. """
|
||||
super(procedureDeleteMultipleTestCase, self).setUp()
|
||||
self = funcs_utils.set_up(self)
|
||||
|
||||
if self.server_type == "pg" and\
|
||||
self.server_version < 110000:
|
||||
message = "Procedures are not supported by PG < 110000."
|
||||
self.skipTest(message)
|
||||
|
||||
func_name = "test_procedure_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
proc_info = funcs_utils.create_procedure(
|
||||
self.server, self.db_name, self.schema_name, func_name,
|
||||
self.server_type, self.server_version)
|
||||
|
||||
func_name_1 = "test_procedure_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
proc_info_1 = funcs_utils.create_procedure(
|
||||
self.server, self.db_name, self.schema_name, func_name_1,
|
||||
self.server_type, self.server_version)
|
||||
|
||||
data = {'ids': [proc_info[0], proc_info_1[0]]}
|
||||
response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
@ -0,0 +1,59 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as funcs_utils
|
||||
|
||||
|
||||
class TriggerFuncDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete the trigger function under schema node. """
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
# Fetching default URL for trigger function node.
|
||||
('Fetch Trigger Function Node URL',
|
||||
dict(url='/browser/trigger_function/obj/'))
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete trigger function under database node. """
|
||||
super(TriggerFuncDeleteMultipleTestCase, self).setUp()
|
||||
self = funcs_utils.set_up(self)
|
||||
|
||||
func_name = "test_event_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
function_info = funcs_utils.create_trigger_function(
|
||||
self.server, self.db_name, self.schema_name, func_name,
|
||||
self.server_version)
|
||||
|
||||
func_name_1 = "test_event_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
function_info_1 = funcs_utils.create_trigger_function(
|
||||
self.server, self.db_name, self.schema_name, func_name_1,
|
||||
self.server_version)
|
||||
|
||||
data = {'ids': [function_info[0], function_info_1[0]]}
|
||||
response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
follow_redirects=True,
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
@ -99,9 +99,9 @@ class PackageView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -412,7 +412,7 @@ class PackageView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition(action='delete')
|
||||
def delete(self, gid, sid, did, scid, pkgid):
|
||||
def delete(self, gid, sid, did, scid, pkgid=None):
|
||||
"""
|
||||
This function will drop the object
|
||||
|
||||
@ -426,6 +426,14 @@ class PackageView(PGChildNodeView):
|
||||
Returns:
|
||||
|
||||
"""
|
||||
|
||||
if pkgid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [pkgid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -434,44 +442,40 @@ class PackageView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']), scid=scid,
|
||||
pkgid=pkgid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for pkgid in data['ids']:
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
scid=scid,
|
||||
pkgid=pkgid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified package could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified package could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
res['rows'][0]['schema'] = self.schema
|
||||
res['rows'][0]['schema'] = self.schema
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
data=res['rows'][0],
|
||||
cascade=cascade)
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=res['rows'][0],
|
||||
cascade=cascade)
|
||||
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=_("Package dropped"),
|
||||
data={
|
||||
'id': pkgid,
|
||||
'scid': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=_("Package dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -12,6 +12,8 @@ define('pgadmin.node.edbfunc', [
|
||||
label: gettext('Functions'),
|
||||
type: 'coll-edbfunc',
|
||||
columns: ['name', 'funcowner', 'description'],
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
@ -37,6 +39,7 @@ define('pgadmin.node.edbfunc', [
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
|
@ -16,6 +16,8 @@ define('pgadmin.node.edbproc', [
|
||||
type: 'coll-edbproc',
|
||||
columns: ['name', 'funcowner', 'description'],
|
||||
hasStatistics: true,
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@ define('pgadmin.node.edbvar', [
|
||||
label: gettext('Variables'),
|
||||
type: 'coll-edbvar',
|
||||
columns: ['name', 'funcowner', 'description'],
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
@ -36,6 +38,7 @@ define('pgadmin.node.edbvar', [
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
|
@ -73,6 +73,7 @@ define('pgadmin.node.package', [
|
||||
},
|
||||
// Define the model for package node.
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
|
@ -0,0 +1,101 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils import server_utils as server_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as package_utils
|
||||
|
||||
|
||||
class PackageDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will delete new package under test schema. """
|
||||
skip_on_database = ['gpdb']
|
||||
|
||||
scenarios = [
|
||||
# Fetching default URL for package node.
|
||||
('Fetch Package Node URL', dict(
|
||||
url='/browser/package/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(PackageDeleteMultipleTestCase, self).setUp()
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
server_con = server_utils.connect_server(self, self.server_id)
|
||||
|
||||
if server_con:
|
||||
if "type" in server_con["data"]:
|
||||
if server_con["data"]["type"] == "pg":
|
||||
message = "Packages are not supported by PG."
|
||||
self.skipTest(message)
|
||||
|
||||
self.pkg_name = "pkg_%s" % str(uuid.uuid4())[1:8]
|
||||
self.proc_name = "proc_%s" % str(uuid.uuid4())[1:8]
|
||||
|
||||
self.pkg_name_1 = "pkg_%s" % str(uuid.uuid4())[1:8]
|
||||
self.proc_name_1 = "proc_%s" % str(uuid.uuid4())[1:8]
|
||||
|
||||
self.package_ids = [package_utils.create_package(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.pkg_name,
|
||||
self.proc_name),
|
||||
package_utils.create_package(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.pkg_name_1,
|
||||
self.proc_name_1)
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete package under test schema. """
|
||||
|
||||
db_con = database_utils.connect_database(self,
|
||||
utils.SERVER_GROUP,
|
||||
self.server_id,
|
||||
self.db_id)
|
||||
|
||||
if not db_con["info"] == "Database connected.":
|
||||
raise Exception("Could not connect to database.")
|
||||
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema.")
|
||||
|
||||
data = {'ids': self.package_ids}
|
||||
delete_response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
|
||||
self.assertEquals(delete_response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
"""This function disconnect the test database."""
|
||||
|
||||
database_utils.disconnect_database(self, self.server_id,
|
||||
self.db_id)
|
@ -104,9 +104,9 @@ class SequenceView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -396,7 +396,7 @@ class SequenceView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition(action='delete')
|
||||
def delete(self, gid, sid, did, scid, seid):
|
||||
def delete(self, gid, sid, did, scid, seid=None):
|
||||
"""
|
||||
This function will drop the object
|
||||
|
||||
@ -410,6 +410,13 @@ class SequenceView(PGChildNodeView):
|
||||
Returns:
|
||||
|
||||
"""
|
||||
if seid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [seid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -418,43 +425,37 @@ class SequenceView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
scid=scid, seid=seid
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified sequence could not be found.\n'
|
||||
)
|
||||
for seid in data['ids']:
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
scid=scid, seid=seid
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
data=res['rows'][0], cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified sequence could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
data=res['rows'][0], cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=_("Sequence dropped"),
|
||||
data={
|
||||
'id': seid,
|
||||
'scid': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=_("Sequence dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -61,6 +61,7 @@ define('pgadmin.node.sequence', [
|
||||
},
|
||||
// Define the model for sequence node.
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
|
@ -0,0 +1,93 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as sequence_utils
|
||||
|
||||
|
||||
class SequenceDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will delete added sequence under schema node."""
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
# Fetching default URL for sequence node.
|
||||
('Fetch sequence Node URL', dict(url='/browser/sequence/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(SequenceDeleteMultipleTestCase, self).setUp()
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to add sequence.")
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to add sequence.")
|
||||
self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
self.sequence_name_1 = "test_sequence_delete_%s" %\
|
||||
str(uuid.uuid4())[1:8]
|
||||
|
||||
self.sequence_ids = [sequence_utils.create_sequences(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.sequence_name),
|
||||
sequence_utils.create_sequences(
|
||||
self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.sequence_name_1)
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete added sequence under schema node. """
|
||||
sequence_response = sequence_utils.verify_sequence(self.server,
|
||||
self.db_name,
|
||||
self.sequence_name)
|
||||
if not sequence_response:
|
||||
raise Exception("Could not find the sequence to delete.")
|
||||
|
||||
sequence_response = sequence_utils.verify_sequence(self.server,
|
||||
self.db_name,
|
||||
self.sequence_name_1
|
||||
)
|
||||
if not sequence_response:
|
||||
raise Exception("Could not find the sequence to delete.")
|
||||
|
||||
data = json.dumps({'ids': self.sequence_ids})
|
||||
response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
follow_redirects=True,
|
||||
data=data,
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -11,6 +11,8 @@ define('pgadmin.node.catalog', [
|
||||
label: gettext('Catalogs'),
|
||||
type: 'coll-catalog',
|
||||
columns: ['name', 'namespaceowner', 'description'],
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
// Extend the browser's node class for catalog node
|
||||
|
@ -306,6 +306,7 @@ define('pgadmin.node.schema', [
|
||||
return pgBrowser.Nodes['database'].is_conn_allow.call(this, node);
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
namespaceowner: undefined,
|
||||
|
@ -165,9 +165,9 @@ class SynonymView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -468,7 +468,7 @@ class SynonymView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, syid):
|
||||
def delete(self, gid, sid, did, scid, syid=None):
|
||||
"""
|
||||
This function will delete existing the synonym object
|
||||
|
||||
@ -479,42 +479,44 @@ class SynonymView(PGChildNodeView):
|
||||
scid: Schema ID
|
||||
syid: Synonym ID
|
||||
"""
|
||||
if syid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [syid]}
|
||||
|
||||
# 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)
|
||||
for syid in data['ids']:
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
scid=scid, syid=syid)
|
||||
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if len(res['rows']) > 0:
|
||||
data = res['rows'][0]
|
||||
else:
|
||||
return gone(
|
||||
gettext('The specified synonym could not be found.')
|
||||
)
|
||||
if len(res['rows']) > 0:
|
||||
data = res['rows'][0]
|
||||
else:
|
||||
return gone(
|
||||
gettext('The specified synonym could not be found.')
|
||||
)
|
||||
|
||||
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)
|
||||
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
|
||||
}
|
||||
info=gettext("Synonym dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -0,0 +1,103 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.sequences.tests \
|
||||
import utils as sequence_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils import server_utils as server_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as synonym_utils
|
||||
|
||||
|
||||
class SynonymDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will delete added synonym under schema node."""
|
||||
skip_on_database = ['gpdb']
|
||||
|
||||
scenarios = [
|
||||
# Fetching default URL for synonym node.
|
||||
('Fetch synonym Node URL', dict(url='/browser/synonym/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(SynonymDeleteMultipleTestCase, self).setUp()
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
server_con = server_utils.connect_server(self, self.server_id)
|
||||
if server_con:
|
||||
if "type" in server_con["data"]:
|
||||
if server_con["data"]["type"] == "pg":
|
||||
message = "Synonyms are not supported by PG."
|
||||
self.skipTest(message)
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to add synonym.")
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to add the synonym.")
|
||||
self.sequence_name = "test_sequence_synonym_%s" % \
|
||||
str(uuid.uuid4())[1:8]
|
||||
self.sequence_id = sequence_utils.create_sequences(
|
||||
self.server, self.db_name, self.schema_name, self.sequence_name)
|
||||
self.synonym_name = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
synonym_utils.create_synonym(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.synonym_name,
|
||||
self.sequence_name)
|
||||
self.synonym_name_1 = "test_synonym_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
synonym_utils.create_synonym(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.synonym_name_1,
|
||||
self.sequence_name)
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete synonym under schema node."""
|
||||
|
||||
synonym_response = synonym_utils.verify_synonym(self.server,
|
||||
self.db_name,
|
||||
self.synonym_name)
|
||||
if not synonym_response:
|
||||
raise Exception("No synonym node to delete.")
|
||||
|
||||
synonym_response = synonym_utils.verify_synonym(self.server,
|
||||
self.db_name,
|
||||
self.synonym_name_1)
|
||||
if not synonym_response:
|
||||
raise Exception("No synonym node to delete.")
|
||||
|
||||
data = {'ids': [self.synonym_name, self.synonym_name_1]}
|
||||
response = self.tester.delete(
|
||||
self.url + str(utils.SERVER_GROUP) + '/' +
|
||||
str(self.server_id) + '/' + str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -212,9 +212,9 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -1056,7 +1056,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@BaseTableView.check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid):
|
||||
def delete(self, gid, sid, did, scid, tid=None):
|
||||
"""
|
||||
This function will deletes the table object
|
||||
|
||||
@ -1067,29 +1067,45 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||
scid: Schema ID
|
||||
tid: Table ID
|
||||
"""
|
||||
if tid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [tid]}
|
||||
|
||||
try:
|
||||
SQL = render_template(
|
||||
"/".join([self.table_template_path, 'properties.sql']),
|
||||
did=did, scid=scid, tid=tid,
|
||||
datlastsysoid=self.datlastsysoid
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified table could not be found.\n'
|
||||
)
|
||||
for tid in data['ids']:
|
||||
SQL = render_template(
|
||||
"/".join([self.table_template_path, 'properties.sql']),
|
||||
did=did, scid=scid, tid=tid,
|
||||
datlastsysoid=self.datlastsysoid
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return super(TableView, self).delete(gid, sid, did, scid, tid, res)
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified table could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
status, res = super(TableView, self).delete(gid, sid, did,
|
||||
scid, tid, res)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Table dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
@ -181,7 +181,7 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
|
||||
@ -609,7 +609,7 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid, clid):
|
||||
def delete(self, gid, sid, did, scid, tid, clid=None):
|
||||
"""
|
||||
This function will updates existing the schema object
|
||||
|
||||
@ -621,42 +621,49 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
|
||||
tid: Table ID
|
||||
clid: Column ID
|
||||
"""
|
||||
if clid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [clid]}
|
||||
|
||||
# We will first fetch the column name for current request
|
||||
# so that we create template for dropping column
|
||||
try:
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
tid=tid, clid=clid,
|
||||
show_sys_objects=self.blueprint.show_system_objects
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified column could not be found.\n'
|
||||
)
|
||||
for clid in data['ids']:
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
tid=tid, clid=clid,
|
||||
show_sys_objects=self.blueprint.show_system_objects
|
||||
)
|
||||
|
||||
data = dict(res['rows'][0])
|
||||
# We will add table & schema as well
|
||||
data['schema'] = self.schema
|
||||
data['table'] = self.table
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
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)
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified column could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
data = dict(res['rows'][0])
|
||||
# We will add table & schema as well
|
||||
data['schema'] = self.schema
|
||||
data['table'] = self.table
|
||||
|
||||
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,
|
||||
|
@ -0,0 +1,91 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tables.tests \
|
||||
import utils as tables_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as columns_utils
|
||||
|
||||
|
||||
class ColumnDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will delete column under table node."""
|
||||
scenarios = [
|
||||
('Delete column Node URL', dict(url='/browser/column/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to add a table.")
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to add a table.")
|
||||
self.table_name = "table_column_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.table_id = tables_utils.create_table(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name)
|
||||
self.column_name = "test_column_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.column_name_1 = "test_column_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.column_ids = [columns_utils.create_column(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.column_name),
|
||||
columns_utils.create_column(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.column_name_1)
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will drop column under table node."""
|
||||
col_response = columns_utils.verify_column(self.server, self.db_name,
|
||||
self.column_name)
|
||||
if not col_response:
|
||||
raise Exception("Could not find the column to drop.")
|
||||
|
||||
col_response = columns_utils.verify_column(self.server, self.db_name,
|
||||
self.column_name_1)
|
||||
if not col_response:
|
||||
raise Exception("Could not find the column to drop.")
|
||||
|
||||
data = {'ids': self.column_ids}
|
||||
response = self.tester.delete(self.url + str(utils.SERVER_GROUP) +
|
||||
'/' + str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/' +
|
||||
str(self.table_id) + '/',
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -173,9 +173,9 @@ class CheckConstraintView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -585,7 +585,7 @@ class CheckConstraintView(PGChildNodeView):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid, cid):
|
||||
def delete(self, gid, sid, did, scid, tid, cid=None):
|
||||
"""
|
||||
Drops the Check Constraint object.
|
||||
|
||||
@ -597,45 +597,47 @@ class CheckConstraintView(PGChildNodeView):
|
||||
tid: Check Id
|
||||
cid: Check Constraint Id
|
||||
"""
|
||||
if cid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [cid]}
|
||||
|
||||
try:
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
tid=tid, cid=cid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
for cid in data['ids']:
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
tid=tid, cid=cid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified check constraint could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified check constraint '
|
||||
'could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
data = res['rows'][0]
|
||||
data = res['rows'][0]
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=_("Check constraint dropped."),
|
||||
data={
|
||||
'id': tid,
|
||||
'scid': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=_("Check constraint dropped.")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -84,7 +84,6 @@ define('pgadmin.node.check_constraint', [
|
||||
canDrop: schemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
|
@ -200,9 +200,9 @@ class ExclusionConstraintView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -713,6 +713,13 @@ class ExclusionConstraintView(PGChildNodeView):
|
||||
Returns:
|
||||
|
||||
"""
|
||||
if exid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [exid]}
|
||||
|
||||
# Below code will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -720,46 +727,42 @@ class ExclusionConstraintView(PGChildNodeView):
|
||||
else:
|
||||
cascade = False
|
||||
try:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'get_name.sql']),
|
||||
cid=exid
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified exclusion constraint could not '
|
||||
'be found.\n'
|
||||
)
|
||||
for exid in data['ids']:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'get_name.sql']),
|
||||
cid=exid
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
data = res['rows'][0]
|
||||
data['schema'] = self.schema
|
||||
data['table'] = self.table
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified exclusion constraint could not '
|
||||
'be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
data=data,
|
||||
cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
data = res['rows'][0]
|
||||
data['schema'] = self.schema
|
||||
data['table'] = self.table
|
||||
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data,
|
||||
cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=_("Exclusion constraint dropped."),
|
||||
data={
|
||||
'id': exid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=_("Exclusion constraint dropped.")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -207,9 +207,9 @@ class ForeignKeyConstraintView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -756,6 +756,13 @@ class ForeignKeyConstraintView(PGChildNodeView):
|
||||
Returns:
|
||||
|
||||
"""
|
||||
if fkid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [fkid]}
|
||||
|
||||
# Below code will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -763,43 +770,38 @@ class ForeignKeyConstraintView(PGChildNodeView):
|
||||
else:
|
||||
cascade = False
|
||||
try:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'get_name.sql']), fkid=fkid)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
for fkid in data['ids']:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'get_name.sql']), fkid=fkid)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified foreign key could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified foreign key could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
data = res['rows'][0]
|
||||
data['schema'] = self.schema
|
||||
data['table'] = self.table
|
||||
data = res['rows'][0]
|
||||
data['schema'] = self.schema
|
||||
data['table'] = self.table
|
||||
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
data=data, cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
data=data, cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=_("Foreign key dropped."),
|
||||
data={
|
||||
'id': fkid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=_("Foreign key dropped.")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -220,9 +220,9 @@ class IndexConstraintView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -746,6 +746,13 @@ class IndexConstraintView(PGChildNodeView):
|
||||
Returns:
|
||||
|
||||
"""
|
||||
if cid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [cid]}
|
||||
|
||||
# Below code will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -753,37 +760,39 @@ class IndexConstraintView(PGChildNodeView):
|
||||
else:
|
||||
cascade = False
|
||||
try:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'get_name.sql']),
|
||||
tid=tid,
|
||||
constraint_type=self.constraint_type,
|
||||
cid=cid
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified constraint could not be found.\n'
|
||||
)
|
||||
for cid in data['ids']:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'get_name.sql']),
|
||||
tid=tid,
|
||||
constraint_type=self.constraint_type,
|
||||
cid=cid
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
data = res['rows'][0]
|
||||
data['schema'] = self.schema
|
||||
data['table'] = self.table
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=_(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=_(
|
||||
'The specified constraint could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
sql = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
data=data,
|
||||
cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
data = res['rows'][0]
|
||||
data['schema'] = self.schema
|
||||
data['table'] = self.table
|
||||
|
||||
sql = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data,
|
||||
cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
|
@ -13,6 +13,8 @@ define('pgadmin.node.constraints', [
|
||||
label: gettext('Constraints'),
|
||||
type: 'coll-constraints',
|
||||
columns: ['name', 'comment'],
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -211,9 +211,9 @@ class IndexesView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -704,7 +704,7 @@ class IndexesView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid, idx):
|
||||
def delete(self, gid, sid, did, scid, tid, idx=None):
|
||||
"""
|
||||
This function will updates existing the schema object
|
||||
|
||||
@ -716,6 +716,13 @@ class IndexesView(PGChildNodeView):
|
||||
tid: Table ID
|
||||
idx: Index ID
|
||||
"""
|
||||
if idx is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [idx]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -724,45 +731,42 @@ class IndexesView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# We will first fetch the index name for current request
|
||||
# so that we create template for dropping index
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
did=did, tid=tid, idx=idx, datlastsysoid=self.datlastsysoid
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified index could not be found.\n'
|
||||
)
|
||||
for idx in data['ids']:
|
||||
# We will first fetch the index name for current request
|
||||
# so that we create template for dropping index
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
did=did, tid=tid, idx=idx, datlastsysoid=self.datlastsysoid
|
||||
)
|
||||
|
||||
data = dict(res['rows'][0])
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
data=data, conn=self.conn, cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified index could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
data = dict(res['rows'][0])
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
data=data, conn=self.conn, cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Index is dropped"),
|
||||
data={
|
||||
'id': idx,
|
||||
'tid': tid
|
||||
}
|
||||
info=gettext("Index is dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -0,0 +1,98 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tables.column. \
|
||||
tests import utils as columns_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tables.tests \
|
||||
import utils as tables_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as indexes_utils
|
||||
|
||||
|
||||
class IndexesDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will delete the existing index of column."""
|
||||
scenarios = [
|
||||
('Delete index Node URL', dict(url='/browser/index/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to add a table.")
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to add a table.")
|
||||
self.table_name = "table_column_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.table_id = tables_utils.create_table(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name)
|
||||
self.column_name = "test_column_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.column_id = columns_utils.create_column(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.column_name)
|
||||
self.index_name = "test_index_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.index_name_1 = "test_index_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.index_ids = [indexes_utils.create_index(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.index_name,
|
||||
self.column_name),
|
||||
indexes_utils.create_index(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.index_name_1,
|
||||
self.column_name)
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete index of existing column."""
|
||||
index_response = indexes_utils.verify_index(self.server, self.db_name,
|
||||
self.index_name)
|
||||
if not index_response:
|
||||
raise Exception("Could not find the index to delete.")
|
||||
|
||||
index_response = indexes_utils.verify_index(self.server, self.db_name,
|
||||
self.index_name_1)
|
||||
if not index_response:
|
||||
raise Exception("Could not find the index to delete.")
|
||||
|
||||
data = {'ids': self.index_ids}
|
||||
response = self.tester.delete(self.url + str(utils.SERVER_GROUP) +
|
||||
'/' + str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/' +
|
||||
str(self.table_id) + '/',
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -163,12 +163,12 @@ class RuleView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{
|
||||
'get': 'children'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
@ -382,54 +382,56 @@ class RuleView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid, rid):
|
||||
def delete(self, gid, sid, did, scid, tid, rid=None):
|
||||
"""
|
||||
This function will drop a rule object
|
||||
"""
|
||||
if rid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [rid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
cascade = True if self.cmd == 'delete' else False
|
||||
|
||||
try:
|
||||
# Get name for rule from did
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'delete.sql']), rid=rid)
|
||||
status, res_data = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res_data)
|
||||
for rid in data['ids']:
|
||||
# Get name for rule from did
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'delete.sql']), rid=rid)
|
||||
status, res_data = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res_data)
|
||||
|
||||
if not res_data['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified rule could not be found.\n'
|
||||
if not res_data['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified rule could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# drop rule
|
||||
rset = res_data['rows'][0]
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'delete.sql']),
|
||||
rulename=rset['rulename'],
|
||||
relname=rset['relname'],
|
||||
nspname=rset['nspname'],
|
||||
cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
# drop rule
|
||||
rset = res_data['rows'][0]
|
||||
SQL = render_template("/".join(
|
||||
[self.template_path, 'delete.sql']),
|
||||
rulename=rset['rulename'],
|
||||
relname=rset['relname'],
|
||||
nspname=rset['nspname'],
|
||||
cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Rule dropped"),
|
||||
data={
|
||||
'id': tid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=gettext("Rule dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -0,0 +1,89 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tables.tests \
|
||||
import utils as tables_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as rules_utils
|
||||
|
||||
|
||||
class RulesDeleteTestCase(BaseTestGenerator):
|
||||
"""This class will delete rule under table node."""
|
||||
scenarios = [
|
||||
('Delete rule Node URL', dict(url='/browser/rule/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to delete rule.")
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to delete rule.")
|
||||
self.table_name = "table_column_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.table_id = tables_utils.create_table(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name)
|
||||
self.rule_name = "test_rule_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.rule_name_1 = "test_rule_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.rule_ids = [rules_utils.create_rule(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.rule_name),
|
||||
rules_utils.create_rule(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.rule_name_1),
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete rule under table node."""
|
||||
rule_response = rules_utils.verify_rule(self.server, self.db_name,
|
||||
self.rule_name)
|
||||
if not rule_response:
|
||||
raise Exception("Could not find the rule to delete.")
|
||||
|
||||
rule_response = rules_utils.verify_rule(self.server, self.db_name,
|
||||
self.rule_name_1)
|
||||
if not rule_response:
|
||||
raise Exception("Could not find the rule to delete.")
|
||||
|
||||
data = {'ids': self.rule_ids}
|
||||
response = self.tester.delete(
|
||||
"{0}{1}/{2}/{3}/{4}/{5}/".format(self.url, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id,
|
||||
self.schema_id, self.table_id
|
||||
),
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -228,6 +228,7 @@ define('pgadmin.node.table_partition_utils', [
|
||||
});
|
||||
|
||||
Backform.PartitionsModel = pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
oid: undefined,
|
||||
is_attach: false,
|
||||
|
@ -263,6 +263,7 @@ define('pgadmin.node.table', [
|
||||
},
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
|
@ -0,0 +1,80 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as tables_utils
|
||||
|
||||
|
||||
class TableDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will delete new table under schema node."""
|
||||
scenarios = [
|
||||
# Fetching default URL for table node.
|
||||
('Delete Table', dict(url='/browser/table/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to add a table.")
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to add a table.")
|
||||
self.table_name = "test_table_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.table_id = tables_utils.create_table(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name)
|
||||
self.table_name_1 = "test_table_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.table_id_1 = tables_utils.create_table(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name_1
|
||||
)
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete added table under schema node."""
|
||||
table_response = tables_utils.verify_table(self.server, self.db_name,
|
||||
self.table_id)
|
||||
if not table_response:
|
||||
raise Exception("Could not find the table to delete.")
|
||||
|
||||
table_response = tables_utils.verify_table(self.server, self.db_name,
|
||||
self.table_id_1)
|
||||
if not table_response:
|
||||
raise Exception("Could not find the table to delete.")
|
||||
|
||||
data = {'ids': [self.table_id, self.table_id_1]}
|
||||
response = self.tester.delete(self.url + str(utils.SERVER_GROUP) +
|
||||
'/' + str(self.server_id) + '/' +
|
||||
str(self.db_id) + '/' +
|
||||
str(self.schema_id) + '/',
|
||||
data=json.dumps(data),
|
||||
content_type='html/json',
|
||||
follow_redirects=True)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -238,9 +238,9 @@ class TriggerView(PGChildNodeView):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -671,7 +671,7 @@ class TriggerView(PGChildNodeView):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid, trid):
|
||||
def delete(self, gid, sid, did, scid, tid, trid=None):
|
||||
"""
|
||||
This function will updates existing the trigger object
|
||||
|
||||
@ -683,6 +683,13 @@ class TriggerView(PGChildNodeView):
|
||||
tid: Table ID
|
||||
trid: Trigger ID
|
||||
"""
|
||||
if trid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [trid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
@ -691,44 +698,44 @@ class TriggerView(PGChildNodeView):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
# We will first fetch the trigger name for current request
|
||||
# so that we create template for dropping trigger
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
tid=tid, trid=trid,
|
||||
datlastsysoid=self.datlastsysoid)
|
||||
for trid in data['ids']:
|
||||
# We will first fetch the trigger name for current request
|
||||
# so that we create template for dropping trigger
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
tid=tid, trid=trid,
|
||||
datlastsysoid=self.datlastsysoid)
|
||||
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified trigger could not be found.\n'
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified trigger could not be found.\n'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
data = dict(res['rows'][0])
|
||||
data = dict(res['rows'][0])
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data, conn=self.conn, cascade=cascade)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data,
|
||||
conn=self.conn,
|
||||
cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Trigger is dropped"),
|
||||
data={
|
||||
'id': trid,
|
||||
'tid': tid
|
||||
}
|
||||
info=gettext("Trigger is dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -181,6 +181,7 @@ define('pgadmin.node.trigger', [
|
||||
canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
is_row_trigger: true,
|
||||
|
@ -0,0 +1,103 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.functions.tests \
|
||||
import utils as trigger_funcs_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tables.tests \
|
||||
import utils as tables_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as triggers_utils
|
||||
|
||||
|
||||
class TriggersDeleteTestCase(BaseTestGenerator):
|
||||
"""This class will delete trigger under table node."""
|
||||
skip_on_database = ['gpdb']
|
||||
scenarios = [
|
||||
('Delete trigger Node URL', dict(url='/browser/trigger/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(TriggersDeleteTestCase, self).setUp()
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to delete trigger.")
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to delete trigger.")
|
||||
self.table_name = "table_trigger_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.table_id = tables_utils.create_table(self.server, self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name)
|
||||
self.func_name = "trigger_func_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
self.function_info = \
|
||||
trigger_funcs_utils.create_trigger_function_with_trigger(
|
||||
self.server, self.db_name, self.schema_name, self.func_name)
|
||||
self.trigger_name = "test_trigger_delete_%s" % (str(uuid.uuid4())[1:8])
|
||||
self.trigger_name_1 = "test_trigger_delete_%s" %\
|
||||
(str(uuid.uuid4())[1:8])
|
||||
self.trigger_ids = [triggers_utils.create_trigger(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.trigger_name,
|
||||
self.func_name),
|
||||
triggers_utils.create_trigger(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.table_name,
|
||||
self.trigger_name_1,
|
||||
self.func_name)
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete trigger under table node."""
|
||||
trigger_response = triggers_utils.verify_trigger(self.server,
|
||||
self.db_name,
|
||||
self.trigger_name)
|
||||
if not trigger_response:
|
||||
raise Exception("Could not find the trigger to delete.")
|
||||
trigger_response = triggers_utils.verify_trigger(self.server,
|
||||
self.db_name,
|
||||
self.trigger_name_1)
|
||||
if not trigger_response:
|
||||
raise Exception("Could not find the trigger to delete.")
|
||||
|
||||
data = {'ids': self.trigger_ids}
|
||||
response = self.tester.delete(
|
||||
"{0}{1}/{2}/{3}/{4}/{5}/".format(self.url, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id,
|
||||
self.schema_id, self.table_id
|
||||
),
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -2363,16 +2363,12 @@ class BaseTableView(PGChildNodeView, BasePartitionTable):
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
return status, res
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Table dropped"),
|
||||
data={
|
||||
'id': tid,
|
||||
'scid': scid
|
||||
}
|
||||
)
|
||||
return True, {
|
||||
'id': tid,
|
||||
'scid': scid
|
||||
}
|
||||
|
||||
def get_schema_and_table_name(self, tid):
|
||||
"""
|
||||
|
@ -0,0 +1,88 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as schema_utils
|
||||
|
||||
|
||||
class SchemaDeleteMultipleTestCase(BaseTestGenerator):
|
||||
""" This class will add new schema under database node. """
|
||||
|
||||
scenarios = [
|
||||
# Fetching default URL for extension node.
|
||||
('Check Schema Node URL', dict(url='/browser/schema/obj/'))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.database_info = parent_node_dict["database"][-1]
|
||||
self.db_name = self.database_info["db_name"]
|
||||
# Change the db name, so that schema will create in newly created db
|
||||
self.schema_names = ["schema_get_%s" % str(uuid.uuid4())[1:8],
|
||||
"schema_get_%s" % str(uuid.uuid4())[1:8]]
|
||||
connection = utils.get_db_connection(self.db_name,
|
||||
self.server['username'],
|
||||
self.server['db_password'],
|
||||
self.server['host'],
|
||||
self.server['port'])
|
||||
self.schema_details = schema_utils.create_schema(connection,
|
||||
self.schema_names[0])
|
||||
connection = utils.get_db_connection(self.db_name,
|
||||
self.server['username'],
|
||||
self.server['db_password'],
|
||||
self.server['host'],
|
||||
self.server['port'])
|
||||
self.schema_details_1 = schema_utils.create_schema(
|
||||
connection,
|
||||
self.schema_names[1]
|
||||
)
|
||||
|
||||
def runTest(self):
|
||||
""" This function will delete schema under database node. """
|
||||
server_id = self.database_info["server_id"]
|
||||
db_id = self.database_info["db_id"]
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
server_id, db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to delete the"
|
||||
" schema.")
|
||||
|
||||
schema_id = self.schema_details[0]
|
||||
schema_name = self.schema_details[1]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to delete.")
|
||||
|
||||
schema_id = self.schema_details_1[0]
|
||||
schema_name = self.schema_details_1[1]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to delete.")
|
||||
|
||||
data = {'ids': [self.schema_details[0], self.schema_details_1[0]]}
|
||||
response = self.tester.delete(self.url + str(utils.SERVER_GROUP) +
|
||||
'/' + str(server_id) + '/' +
|
||||
str(db_id),
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json')
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
@ -190,9 +190,9 @@ class TypeView(PGChildNodeView, DataTypeReader):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@ -1063,7 +1063,7 @@ class TypeView(PGChildNodeView, DataTypeReader):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid):
|
||||
def delete(self, gid, sid, did, scid, tid=None):
|
||||
"""
|
||||
This function will updates existing the type object
|
||||
|
||||
@ -1074,6 +1074,12 @@ class TypeView(PGChildNodeView, DataTypeReader):
|
||||
scid: Schema ID
|
||||
tid: Type ID
|
||||
"""
|
||||
if tid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [tid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
@ -1083,37 +1089,40 @@ class TypeView(PGChildNodeView, DataTypeReader):
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
scid=scid, tid=tid,
|
||||
datlastsysoid=self.datlastsysoid,
|
||||
show_system_objects=self.blueprint.show_system_objects
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified type could not be found.\n'
|
||||
)
|
||||
for tid in data['ids']:
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path,
|
||||
'properties.sql']),
|
||||
scid=scid, tid=tid,
|
||||
datlastsysoid=self.datlastsysoid,
|
||||
show_system_objects=self.blueprint.show_system_objects
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
# Making copy of output for future use
|
||||
data = dict(res['rows'][0])
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified type could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
data=data, cascade=cascade, conn=self.conn)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
# Making copy of output for future use
|
||||
data = dict(res['rows'][0])
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data,
|
||||
cascade=cascade,
|
||||
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,
|
||||
|
@ -270,12 +270,12 @@ class ViewNode(PGChildNodeView, VacuumSettings):
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'children': [{
|
||||
'get': 'children'
|
||||
}],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
@ -557,60 +557,61 @@ class ViewNode(PGChildNodeView, VacuumSettings):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, scid, vid):
|
||||
def delete(self, gid, sid, did, scid, vid=None):
|
||||
"""
|
||||
This function will drop a view object
|
||||
"""
|
||||
if vid is None:
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data, encoding='utf-8'
|
||||
)
|
||||
else:
|
||||
data = {'ids': [vid]}
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
cascade = True if self.cmd == 'delete' else False
|
||||
|
||||
try:
|
||||
# Get name for view from vid
|
||||
SQL = render_template(
|
||||
"/".join([
|
||||
self.template_path, 'sql/properties.sql'
|
||||
]),
|
||||
did=did,
|
||||
vid=vid,
|
||||
datlastsysoid=self.datlastsysoid
|
||||
)
|
||||
status, res_data = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res_data)
|
||||
|
||||
if not res_data['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified view could not be found.\n'
|
||||
)
|
||||
for vid in data['ids']:
|
||||
# Get name for view from vid
|
||||
SQL = render_template(
|
||||
"/".join([
|
||||
self.template_path, 'sql/properties.sql'
|
||||
]),
|
||||
did=did,
|
||||
vid=vid,
|
||||
datlastsysoid=self.datlastsysoid
|
||||
)
|
||||
status, res_data = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res_data)
|
||||
|
||||
# drop view
|
||||
SQL = render_template(
|
||||
"/".join([
|
||||
self.template_path, 'sql/delete.sql'
|
||||
]),
|
||||
nspname=res_data['rows'][0]['schema'],
|
||||
name=res_data['rows'][0]['name'], cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if not res_data['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified view could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
# drop view
|
||||
SQL = render_template(
|
||||
"/".join([
|
||||
self.template_path, 'sql/delete.sql'
|
||||
]),
|
||||
nspname=res_data['rows'][0]['schema'],
|
||||
name=res_data['rows'][0]['name'], cascade=cascade
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("View dropped"),
|
||||
data={
|
||||
'id': vid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
info=gettext("View dropped")
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
@ -115,6 +115,7 @@ define('pgadmin.node.mview', [
|
||||
properties of the model in schema.
|
||||
*/
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
if (_.size(attrs) === 0) {
|
||||
// Set Selected Schema and Current User
|
||||
|
@ -85,6 +85,7 @@ define('pgadmin.node.view', [
|
||||
properties of the model in schema.
|
||||
*/
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
initialize: function(attrs, args) {
|
||||
if (_.size(attrs) === 0) {
|
||||
// Set Selected Schema and, Current User
|
||||
|
@ -0,0 +1,104 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
|
||||
utils as schema_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||
database_utils
|
||||
from pgadmin.utils import server_utils as server_utils
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from regression import parent_node_dict
|
||||
from regression.python_test_utils import test_utils as utils
|
||||
from . import utils as views_utils
|
||||
|
||||
|
||||
class ViewsDeleteMultipleTestCase(BaseTestGenerator):
|
||||
"""This class will delete the view/mview under schema node."""
|
||||
view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \
|
||||
"ALTER TABLE %s.%s OWNER TO %s"
|
||||
m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \
|
||||
"SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \
|
||||
" TO %s"
|
||||
scenarios = [
|
||||
('Delete multiple view under schema node', dict(
|
||||
url='/browser/view/obj/',
|
||||
view_name=["test_view_delete_%s" % (str(uuid.uuid4())[1:8]),
|
||||
"test_view_delete_%s" % (str(uuid.uuid4())[1:8])],
|
||||
sql_query=view_sql)),
|
||||
('Delete multiple materialized view under schema node',
|
||||
dict(url='/browser/mview/obj/',
|
||||
view_name=["test_mview_delete_%s" % (str(uuid.uuid4())[1:8]),
|
||||
"test_mview_delete_%s" % (str(uuid.uuid4())[1:8])],
|
||||
sql_query=m_view_sql))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.db_name = parent_node_dict["database"][-1]["db_name"]
|
||||
schema_info = parent_node_dict["schema"][-1]
|
||||
self.server_id = schema_info["server_id"]
|
||||
self.db_id = schema_info["db_id"]
|
||||
server_response = server_utils.connect_server(self, self.server_id)
|
||||
|
||||
if server_response["data"]["version"] < 90300 and "mview" in self.url:
|
||||
message = "Materialized Views are not supported by PG9.2 " \
|
||||
"and PPAS9.2 and below."
|
||||
self.skipTest(message)
|
||||
|
||||
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id)
|
||||
if not db_con['data']["connected"]:
|
||||
raise Exception("Could not connect to database to delete view.")
|
||||
self.schema_id = schema_info["schema_id"]
|
||||
self.schema_name = schema_info["schema_name"]
|
||||
schema_response = schema_utils.verify_schemas(self.server,
|
||||
self.db_name,
|
||||
self.schema_name)
|
||||
if not schema_response:
|
||||
raise Exception("Could not find the schema to delete the view.")
|
||||
self.view_ids = [views_utils.create_view(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.sql_query,
|
||||
self.view_name[0]),
|
||||
views_utils.create_view(self.server,
|
||||
self.db_name,
|
||||
self.schema_name,
|
||||
self.sql_query,
|
||||
self.view_name[1])
|
||||
]
|
||||
|
||||
def runTest(self):
|
||||
"""This function will delete the view/mview under schema node."""
|
||||
view_response = views_utils.verify_view(self.server, self.db_name,
|
||||
self.view_name[0])
|
||||
if not view_response:
|
||||
raise Exception("Could not find the view to delete.")
|
||||
view_response = views_utils.verify_view(self.server, self.db_name,
|
||||
self.view_name[1])
|
||||
if not view_response:
|
||||
raise Exception("Could not find the view to delete.")
|
||||
|
||||
data = {'ids': self.view_ids}
|
||||
response = self.tester.delete(
|
||||
"{0}{1}/{2}/{3}/{4}/".format(self.url, utils.SERVER_GROUP,
|
||||
self.server_id, self.db_id,
|
||||
self.schema_id
|
||||
),
|
||||
follow_redirects=True,
|
||||
data=json.dumps(data),
|
||||
content_type='html/json'
|
||||
)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
def tearDown(self):
|
||||
# Disconnect the database
|
||||
database_utils.disconnect_database(self, self.server_id, self.db_id)
|
@ -13,6 +13,8 @@ define('pgadmin.node.database', [
|
||||
type: 'coll-database',
|
||||
columns: ['name', 'datowner', 'comments'],
|
||||
hasStatistics: true,
|
||||
canDrop: true,
|
||||
canDropCascade: false,
|
||||
statsPrettifyFields: ['Size', 'Size of temporary files'],
|
||||
});
|
||||
}
|
||||
@ -257,6 +259,7 @@ define('pgadmin.node.database', [
|
||||
},
|
||||
},
|
||||
model: pgBrowser.Node.Model.extend({
|
||||
idAttribute: 'did',
|
||||
defaults: {
|
||||
name: undefined,
|
||||
owner: undefined,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user