Better handling the non-ascii characters for different database objects.

Using 'psycopg2.extensions.UNICODE' (for Python < 3) in the psycopg2
driver for proper conversation of unicode characters. Also - adjusted
the string typecaster to take care of different character types (char,
character, text, name, character varying, and their array types).

Reviewed by: Dave Page, Murtuza Zabuawala & Akshay Joshi
This commit is contained in:
Harshal Dhumal
2017-03-02 15:05:41 +05:30
committed by Ashesh Vashi
parent af29eac6ba
commit ffa8d94e76
34 changed files with 364 additions and 380 deletions

View File

@@ -194,8 +194,6 @@ class DatabaseView(PGChildNodeView):
for row in rset['rows']: for row in rset['rows']:
dbname = row['name'] dbname = row['name']
if hasattr(str, 'decode'):
dbname = dbname.decode('utf-8')
if self.manager.db == dbname: if self.manager.db == dbname:
connected = True connected = True
canDrop = canDisConn = False canDrop = canDisConn = False
@@ -253,8 +251,6 @@ class DatabaseView(PGChildNodeView):
for row in rset['rows']: for row in rset['rows']:
db = row['name'] db = row['name']
if hasattr(str, 'decode'):
db = db.decode('utf-8')
if self.manager.db == db: if self.manager.db == db:
connected = True connected = True
else: else:
@@ -905,9 +901,7 @@ class DatabaseView(PGChildNodeView):
frmtd_variables = parse_variables_from_db(res1['rows']) frmtd_variables = parse_variables_from_db(res1['rows'])
result.update(frmtd_variables) result.update(frmtd_variables)
sql_header = "-- Database: {0}\n\n-- ".format(result['name']) sql_header = u"-- Database: {0}\n\n-- ".format(result['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template( sql_header += render_template(
"/".join([self.template_path, 'delete.sql']), "/".join([self.template_path, 'delete.sql']),

View File

@@ -502,18 +502,15 @@ class CastView(PGChildNodeView):
:return: :return:
""" """
data = request.args data = request.args
try: sql, name = self.get_sql(gid, sid, did, data, cid)
sql, name = self.get_sql(gid, sid, did, data, cid) sql = sql.strip('\n').strip(' ')
sql = sql.strip('\n').strip(' ') if sql == '':
if sql == '': sql = "--modified SQL"
sql = "--modified SQL"
return make_json_response( return make_json_response(
data=sql, data=sql,
status=200 status=200
) )
except Exception as e:
return internal_server_error(errormsg=str(e))
def get_sql(self, gid, sid, did, data, cid=None): def get_sql(self, gid, sid, did, data, cid=None):
""" """
@@ -544,13 +541,13 @@ class CastView(PGChildNodeView):
"/".join([self.template_path, 'update.sql']), "/".join([self.template_path, 'update.sql']),
data=data, o_data=old_data data=data, o_data=old_data
) )
return str(sql), data['name'] if 'name' in data else old_data['name'] return sql, data['name'] if 'name' in data else old_data['name']
else: else:
if 'srctyp' in data and 'trgtyp' in data: if 'srctyp' in data and 'trgtyp' in data:
sql = render_template("/".join([self.template_path, 'create.sql']), data=data, conn=self.conn) sql = render_template("/".join([self.template_path, 'create.sql']), data=data, conn=self.conn)
else: else:
return "-- incomplete definition", None return u"-- incomplete definition", None
return str(sql), data['srctyp'] + "->" + data["trgtyp"] return sql, data['srctyp'] + "->" + data["trgtyp"]
@check_precondition @check_precondition
def get_functions(self, gid, sid, did, cid=None): def get_functions(self, gid, sid, did, cid=None):

View File

@@ -623,39 +623,33 @@ class EventTriggerView(PGChildNodeView):
Returns: Returns:
""" """
try: sql = render_template("/".join([self.template_path, 'properties.sql']), etid=etid)
sql = render_template("/".join([self.template_path, 'properties.sql']), etid=etid) status, res = self.conn.execute_dict(sql)
status, res = self.conn.execute_dict(sql) if not status:
if not status: return internal_server_error(errormsg=res)
return internal_server_error(errormsg=res)
result = res['rows'][0] result = res['rows'][0]
result = self._formatter(result) result = self._formatter(result)
sql = render_template("/".join([self.template_path, 'create.sql']), data=result, conn=self.conn) sql = render_template("/".join([self.template_path, 'create.sql']), data=result, conn=self.conn)
sql += "\n\n" sql += "\n\n"
sql += render_template("/".join([self.template_path, 'grant.sql']), data=result, conn=self.conn) sql += render_template("/".join([self.template_path, 'grant.sql']), data=result, conn=self.conn)
db_sql = render_template("/".join([self.template_path, 'get_db.sql']), did=did) db_sql = render_template("/".join([self.template_path, 'get_db.sql']), did=did)
status, db_name = self.conn.execute_scalar(db_sql) status, db_name = self.conn.execute_scalar(db_sql)
if not status: if not status:
return internal_server_error(errormsg=db_name) return internal_server_error(errormsg=db_name)
sql_header = "-- Event Trigger: {0} on database {1}\n\n-- ".format(result['name'], db_name) sql_header = u"-- Event Trigger: {0} on database {1}\n\n-- ".format(result['name'], db_name)
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template( sql_header += render_template(
"/".join([self.template_path, 'delete.sql']), "/".join([self.template_path, 'delete.sql']),
name=result['name'], ) name=result['name'], )
sql_header += "\n" sql_header += "\n"
sql = sql_header + sql sql = sql_header + sql
return ajax_response(response=sql) return ajax_response(response=sql)
except Exception as e:
return ajax_response(response=str(e))
@check_precondition @check_precondition
def get_event_funcs(self, gid, sid, did, etid=None): def get_event_funcs(self, gid, sid, did, etid=None):

View File

@@ -682,15 +682,12 @@ class ForeignDataWrapperView(PGChildNodeView):
) )
sql += "\n" sql += "\n"
sql_header = """-- Foreign Data Wrapper: {0} sql_header = u"""-- Foreign Data Wrapper: {0}
-- DROP FOREIGN DATA WRAPPER {0} -- DROP FOREIGN DATA WRAPPER {0}
""".format(res['rows'][0]['name']) """.format(res['rows'][0]['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql = sql_header + sql sql = sql_header + sql
return ajax_response(response=sql.strip('\n')) return ajax_response(response=sql.strip('\n'))

View File

@@ -703,13 +703,11 @@ class ForeignServerView(PGChildNodeView):
conn=self.conn) conn=self.conn)
sql += "\n" sql += "\n"
sql_header = """-- Foreign Server: {0} sql_header = u"""-- Foreign Server: {0}
-- DROP SERVER {0} -- DROP SERVER {0}
""".format(res['rows'][0]['name']) """.format(res['rows'][0]['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql = sql_header + sql sql = sql_header + sql

View File

@@ -709,13 +709,11 @@ class UserMappingView(PGChildNodeView):
conn=self.conn) conn=self.conn)
sql += "\n" sql += "\n"
sql_header = """-- User Mapping : {0} sql_header = u"""-- User Mapping : {0}
-- DROP USER MAPPING FOR {0} SERVER {1} -- DROP USER MAPPING FOR {0} SERVER {1}
""".format(res['rows'][0]['name'], fdw_data['name']) """.format(res['rows'][0]['name'], fdw_data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql = sql_header + sql sql = sql_header + sql

View File

@@ -805,9 +805,7 @@ It may have been removed by another user.
_=gettext, data=data, conn=self.conn _=gettext, data=data, conn=self.conn
) )
sql_header = "-- SCHEMA: {0}\n\n-- ".format(data['name']) sql_header = u"-- SCHEMA: {0}\n\n-- ".format(data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
# drop schema # drop schema
sql_header += render_template( sql_header += render_template(
@@ -991,14 +989,12 @@ It may have been removed by another user.
_=gettext, data=old_data, conn=self.conn _=gettext, data=old_data, conn=self.conn
) )
sql_header = """ sql_header = u"""
-- CATALOG: {0} -- CATALOG: {0}
-- DROP SCHEMA {0};( -- DROP SCHEMA {0};(
""".format(old_data['name']) """.format(old_data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
SQL = sql_header + SQL SQL = sql_header + SQL

View File

@@ -650,9 +650,8 @@ class CollationView(PGChildNodeView):
'create.sql']), 'create.sql']),
data=data, conn=self.conn) data=data, conn=self.conn)
sql_header = "-- Collation: {0};\n\n-- ".format(data['name']) sql_header = u"-- Collation: {0};\n\n-- ".format(data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template("/".join([self.template_path, sql_header += render_template("/".join([self.template_path,
'delete.sql']), 'delete.sql']),
name=data['name']) name=data['name'])

View File

@@ -699,14 +699,11 @@ AND relkind != 'c'))"""
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'create.sql']), data=data) 'create.sql']), data=data)
sql_header = """-- DOMAIN: {0} sql_header = u"""-- DOMAIN: {0}
-- DROP DOMAIN {0}; -- DROP DOMAIN {0};
""".format(data['basensp'] + '.' + data['name']) """.format(self.qtIdent(self.conn, data['basensp'], data['name']))
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
SQL = sql_header + SQL SQL = sql_header + SQL
return ajax_response(response=SQL.strip('\n')) return ajax_response(response=SQL.strip('\n'))

View File

@@ -601,13 +601,12 @@ class DomainConstraintView(PGChildNodeView):
'create.sql']), 'create.sql']),
data=data, domain=domain, schema=schema) data=data, domain=domain, schema=schema)
sql_header = """-- CHECK: {1}.{0} sql_header = u"""-- CHECK: {1}.{0}
-- ALTER DOMAIN {1} DROP CONSTRAINT {0}; -- ALTER DOMAIN {1} DROP CONSTRAINT {0};
""".format(data['name'], schema + '.' + domain) """.format(self.qtIdent(self.conn, data['name']),
if hasattr(str, 'decode'): self.qtIdent(self.conn, schema, domain))
sql_header = sql_header.decode('utf-8')
SQL = sql_header + SQL SQL = sql_header + SQL

View File

@@ -821,13 +821,11 @@ shifted to the another schema.
SQL = render_template("/".join([self.template_path, SQL = render_template("/".join([self.template_path,
'create.sql']), data=data) 'create.sql']), data=data)
sql_header = """-- {0}: {1} sql_header = u"""-- FOREIGN TABLE: {0}
-- DROP {0} {1}; -- DROP FOREIGN TABLE {0};
""".format('FOREIGN TABLE', data['basensp'] + "." + data['name']) """.format(self.qtIdent(self.conn, data['basensp'], data['name']))
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
SQL = sql_header + SQL SQL = sql_header + SQL

View File

@@ -594,18 +594,16 @@ class FtsConfigurationView(PGChildNodeView):
data[k] = json.loads(v, encoding='utf-8') data[k] = json.loads(v, encoding='utf-8')
except ValueError: except ValueError:
data[k] = v data[k] = v
try:
# Fetch sql query for modified data
SQL, name = self.get_sql(gid, sid, did, scid, data, cfgid)
if SQL == '':
SQL = "-- No change"
return make_json_response( # Fetch sql query for modified data
data=SQL, SQL, name = self.get_sql(gid, sid, did, scid, data, cfgid)
status=200 if SQL == '':
) SQL = "-- No change"
except Exception as e:
return internal_server_error(errormsg=str(e)) return make_json_response(
data=SQL,
status=200
)
def get_sql(self, gid, sid, did, scid, data, cfgid=None): def get_sql(self, gid, sid, did, scid, data, cfgid=None):
""" """
@@ -668,7 +666,7 @@ class FtsConfigurationView(PGChildNodeView):
data=new_data, o_data=old_data data=new_data, o_data=old_data
) )
# Fetch sql query for modified data # Fetch sql query for modified data
return str(sql.strip('\n')), data['name'] if 'name' in data else old_data['name'] return sql.strip('\n'), data['name'] if 'name' in data else old_data['name']
else: else:
# Fetch schema name from schema oid # Fetch schema name from schema oid
sql = render_template( sql = render_template(
@@ -692,8 +690,8 @@ class FtsConfigurationView(PGChildNodeView):
conn=self.conn conn=self.conn
) )
else: else:
sql = "-- incomplete definition" sql = u"-- incomplete definition"
return str(sql.strip('\n')), data['name'] return sql.strip('\n'), data['name']
@check_precondition @check_precondition
def parsers(self, gid, sid, did, scid): def parsers(self, gid, sid, did, scid):

View File

@@ -579,18 +579,15 @@ class FtsDictionaryView(PGChildNodeView):
except ValueError: except ValueError:
data[k] = v data[k] = v
try: # Fetch sql query for modified data
# Fetch sql query for modified data SQL, name = self.get_sql(gid, sid, did, scid, data, dcid)
SQL, name = self.get_sql(gid, sid, did, scid, data, dcid) if SQL == '':
if SQL == '': SQL = "--modified SQL"
SQL = "--modified SQL"
return make_json_response( return make_json_response(
data=SQL, data=SQL,
status=200 status=200
) )
except Exception as e:
return internal_server_error(errormsg=str(e))
def get_sql(self, gid, sid, did, scid, data, dcid=None): def get_sql(self, gid, sid, did, scid, data, dcid=None):
""" """
@@ -653,7 +650,7 @@ class FtsDictionaryView(PGChildNodeView):
data=new_data, o_data=old_data data=new_data, o_data=old_data
) )
# Fetch sql query for modified data # Fetch sql query for modified data
return str(sql.strip('\n')), data['name'] if 'name' in data else old_data['name'] return sql.strip('\n'), data['name'] if 'name' in data else old_data['name']
else: else:
# Fetch schema name from schema oid # Fetch schema name from schema oid
sql = render_template("/".join([self.template_path, 'schema.sql']), sql = render_template("/".join([self.template_path, 'schema.sql']),
@@ -676,8 +673,8 @@ class FtsDictionaryView(PGChildNodeView):
conn=self.conn conn=self.conn
) )
else: else:
sql = "-- incomplete definition" sql = u"-- incomplete definition"
return str(sql.strip('\n')), data['name'] return sql.strip('\n'), data['name']
@check_precondition @check_precondition
def fetch_templates(self, gid, sid, did, scid): def fetch_templates(self, gid, sid, did, scid):

View File

@@ -5,9 +5,9 @@ SELECT
FROM FROM
( (
SELECT SELECT
E'-- Text Search Dictionary: ' || nspname || E'.' || dict.dictname || E'-- Text Search Dictionary: ' || quote_ident(nspname) || E'.' || quote_ident(dict.dictname) ||
E'\n\n-- DROP TEXT SEARCH DICTIONARY ' || nspname || E'.' || dict.dictname || E'\n\n-- DROP TEXT SEARCH DICTIONARY ' || quote_ident(nspname) || E'.' || quote_ident(dict.dictname) ||
E'\n\nCREATE TEXT SEARCH DICTIONARY ' || nspname || E'.' || dict.dictname || E' (\n' || E'\n\nCREATE TEXT SEARCH DICTIONARY ' || quote_ident(nspname) || E'.' || quote_ident(dict.dictname) || E' (\n' ||
E'\tTEMPLATE = ' || template || E'\tTEMPLATE = ' || template ||
CASE CASE
WHEN dict.dictinitoption IS NOT NULL THEN E',\n\t' || dict.dictinitoption WHEN dict.dictinitoption IS NOT NULL THEN E',\n\t' || dict.dictinitoption
@@ -16,7 +16,7 @@ FROM
E'\n);' || E'\n);' ||
CASE CASE
WHEN description IS NOT NULL THEN WHEN description IS NOT NULL THEN
E'\n\nCOMMENT ON TEXT SEARCH DICTIONARY ' || nspname || E'.' || dict.dictname || E'\n\nCOMMENT ON TEXT SEARCH DICTIONARY ' || quote_ident(nspname) || E'.' || quote_ident(dict.dictname) ||
E' IS ' || pg_catalog.quote_literal(description) || E';' E' IS ' || pg_catalog.quote_literal(description) || E';'
ELSE '' END as sql ELSE '' END as sql
FROM FROM

View File

@@ -513,18 +513,16 @@ class FtsParserView(PGChildNodeView):
""" """
data = request.args data = request.args
# Fetch sql query for modified data # Fetch sql query for modified data
try:
# Fetch sql query for modified data
SQL, name = self.get_sql(gid, sid, did, scid, data, pid)
if SQL == '':
SQL = "--modified SQL"
return make_json_response( # Fetch sql query for modified data
data=SQL, SQL, name = self.get_sql(gid, sid, did, scid, data, pid)
status=200 if SQL == '':
) SQL = "--modified SQL"
except Exception as e:
return internal_server_error(errormsg=str(e)) return make_json_response(
data=SQL,
status=200
)
def get_sql(self, gid, sid, did, scid, data, pid=None): def get_sql(self, gid, sid, did, scid, data, pid=None):
""" """
@@ -587,7 +585,7 @@ class FtsParserView(PGChildNodeView):
o_data=old_data o_data=old_data
) )
# Fetch sql query for modified data # Fetch sql query for modified data
return str(sql.strip('\n')), data['name'] if 'name' in data else old_data['name'] return sql.strip('\n'), data['name'] if 'name' in data else old_data['name']
else: else:
# Fetch schema name from schema oid # Fetch schema name from schema oid
sql = render_template( sql = render_template(
@@ -616,7 +614,7 @@ class FtsParserView(PGChildNodeView):
) )
else: else:
sql = "-- incomplete definition" sql = "-- incomplete definition"
return str(sql.strip('\n')), data['name'] return sql.strip('\n'), data['name']
@check_precondition @check_precondition
def start_functions(self, gid, sid, did, scid): def start_functions(self, gid, sid, did, scid):

View File

@@ -5,9 +5,9 @@ SELECT
FROM FROM
( (
SELECT SELECT
E'-- Text Search Parser: ' || nspname || E'.' || prs.prsname || E'-- Text Search Parser: ' || quote_ident(nspname) || E'.' || quote_ident(prs.prsname) ||
E'\n\n-- DROP TEXT SEARCH PARSER ' || nspname || E'.' || prs.prsname || E'\n\n-- DROP TEXT SEARCH PARSER ' || quote_ident(nspname) || E'.' || quote_ident(prs.prsname) ||
E'\n\nCREATE TEXT SEARCH PARSER ' || nspname || E'.' || prs.prsname || E' (\n' || E'\n\nCREATE TEXT SEARCH PARSER ' || quote_ident(nspname) || E'.' || quote_ident(prs.prsname) || E' (\n' ||
E' START = ' || prs.prsstart || E',\n' || E' START = ' || prs.prsstart || E',\n' ||
E' GETTOKEN = ' || prs.prstoken || E',\n' || E' GETTOKEN = ' || prs.prstoken || E',\n' ||
E' END = ' || prs.prsend || E',\n' || E' END = ' || prs.prsend || E',\n' ||
@@ -17,7 +17,7 @@ FROM
ELSE '' END || E'\n);' || ELSE '' END || E'\n);' ||
CASE CASE
WHEN description IS NOT NULL THEN WHEN description IS NOT NULL THEN
E'\n\nCOMMENT ON TEXT SEARCH PARSER ' || nspname || E'.' || prs.prsname || E'\n\nCOMMENT ON TEXT SEARCH PARSER ' || quote_ident(nspname) || E'.' || quote_ident(prs.prsname) ||
E' IS ' || pg_catalog.quote_literal(description) || E';' E' IS ' || pg_catalog.quote_literal(description) || E';'
ELSE '' END as sql ELSE '' END as sql
FROM FROM

View File

@@ -275,7 +275,7 @@ class FtsTemplateView(PGChildNodeView):
status=200 status=200
) )
return gone( return gone(
_("Could not the requested FTS template.") gettext("Could not the requested FTS template.")
) )
@check_precondition @check_precondition
@@ -547,7 +547,7 @@ class FtsTemplateView(PGChildNodeView):
data=new_data, o_data=old_data data=new_data, o_data=old_data
) )
# Fetch sql query for modified data # Fetch sql query for modified data
return str(sql.strip('\n')), data['name'] if 'name' in data else old_data['name'] return sql.strip('\n'), data['name'] if 'name' in data else old_data['name']
else: else:
# Fetch schema name from schema oid # Fetch schema name from schema oid
sql = render_template("/".join([self.template_path, 'schema.sql']), sql = render_template("/".join([self.template_path, 'schema.sql']),
@@ -570,8 +570,8 @@ class FtsTemplateView(PGChildNodeView):
conn=self.conn conn=self.conn
) )
else: else:
sql = "-- incomplete definition" sql = u"-- incomplete definition"
return str(sql.strip('\n')), data['name'] return sql.strip('\n'), data['name']
@check_precondition @check_precondition
def get_lexize(self, gid, sid, did, scid, tid=None): def get_lexize(self, gid, sid, did, scid, tid=None):
@@ -649,7 +649,7 @@ class FtsTemplateView(PGChildNodeView):
status, res = self.conn.execute_scalar(sql) status, res = self.conn.execute_scalar(sql)
if not status: if not status:
return internal_server_error( return internal_server_error(
_( gettext(
"Could not generate reversed engineered Query for the FTS Template.\n{0}").format( "Could not generate reversed engineered Query for the FTS Template.\n{0}").format(
res res
) )
@@ -657,7 +657,7 @@ class FtsTemplateView(PGChildNodeView):
if res is None: if res is None:
return gone( return gone(
_( gettext(
"Could not generate reversed engineered Query for FTS Template node.") "Could not generate reversed engineered Query for FTS Template node.")
) )

View File

@@ -4,16 +4,16 @@ SELECT
FROM FROM
( (
SELECT SELECT
E'-- Text Search Template: ' || nspname || E'.' || tmpl.tmplname || E'-- Text Search Template: ' || quote_ident(nspname) || E'.' || quote_ident(tmpl.tmplname) ||
E'\n\n-- DROP TEXT SEARCH TEMPLATE ' || nspname || E'.' || tmpl.tmplname || E'\n\n-- DROP TEXT SEARCH TEMPLATE ' || quote_ident(nspname) || E'.' || quote_ident(tmpl.tmplname) ||
E'\n\nCREATE TEXT SEARCH TEMPLATE ' || nspname || E'.' || tmpl.tmplname || E' (\n' || E'\n\nCREATE TEXT SEARCH TEMPLATE ' || quote_ident(nspname) || E'.' || quote_ident(tmpl.tmplname) || E' (\n' ||
CASE CASE
WHEN tmpl.tmplinit != '-'::regclass THEN E' INIT = ' || tmpl.tmplinit || E',\n' WHEN tmpl.tmplinit != '-'::regclass THEN E' INIT = ' || tmpl.tmplinit || E',\n'
ELSE '' END || ELSE '' END ||
E' LEXIZE = ' || tmpl.tmpllexize || E'\n);' || E' LEXIZE = ' || tmpl.tmpllexize || E'\n);' ||
CASE CASE
WHEN a.description IS NOT NULL THEN WHEN a.description IS NOT NULL THEN
E'\n\nCOMMENT ON TEXT SEARCH TEMPLATE ' || nspname || E'.' || tmpl.tmplname || E'\n\nCOMMENT ON TEXT SEARCH TEMPLATE ' || quote_ident(nspname) || E'.' || quote_ident(tmpl.tmplname) ||
E' IS ' || pg_catalog.quote_literal(description) || E';' E' IS ' || pg_catalog.quote_literal(description) || E';'
ELSE '' END as sql ELSE '' END as sql
FROM FROM

View File

@@ -955,13 +955,6 @@ class FunctionView(PGChildNodeView, DataTypeReader):
if 'acl' in resp_data: if 'acl' in resp_data:
resp_data['acl'] = parse_priv_to_db(resp_data['acl'], ['X']) resp_data['acl'] = parse_priv_to_db(resp_data['acl'], ['X'])
# generate function signature
header_func_name = '{0}.{1}({2})'.format(
resp_data['pronamespace'],
resp_data['proname'],
resp_data['proargtypenames']
)
# Generate sql for "SQL panel" # Generate sql for "SQL panel"
# func_def is procedure signature with default arguments # func_def is procedure signature with default arguments
# query_for - To distinguish the type of call # query_for - To distinguish the type of call
@@ -982,13 +975,6 @@ class FunctionView(PGChildNodeView, DataTypeReader):
if 'acl' in resp_data: if 'acl' in resp_data:
resp_data['acl'] = parse_priv_to_db(resp_data['acl'], ['X']) resp_data['acl'] = parse_priv_to_db(resp_data['acl'], ['X'])
# generate function signature
header_func_name = '{0}.{1}({2})'.format(
resp_data['pronamespace'],
resp_data['proname'],
resp_data['proargtypenames']
)
SQL = render_template("/".join([self.sql_template_path, SQL = render_template("/".join([self.sql_template_path,
'get_definition.sql'] 'get_definition.sql']
), data=resp_data, ), data=resp_data,
@@ -999,17 +985,7 @@ class FunctionView(PGChildNodeView, DataTypeReader):
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
# Add newline and tab before each argument to format # Add newline and tab before each argument to format
name_with_default_args = res['rows'][0]['name_with_default_args'].replace(', ', ',\r\t').replace('(', '(\r\t') name_with_default_args = res['rows'][0]['name_with_default_args'].replace(', ', ',\r\t').replace('(', '(\r\t')
if hasattr(str, 'decode'):
if resp_data['prosrc']:
resp_data['prosrc'] = resp_data['prosrc'].decode(
'utf-8'
)
if resp_data['prosrc_c']:
resp_data['prosrc_c'] = resp_data['prosrc_c'].decode(
'utf-8'
)
# Generate sql for "SQL panel" # Generate sql for "SQL panel"
# func_def is function signature with default arguments # func_def is function signature with default arguments
@@ -1020,13 +996,16 @@ class FunctionView(PGChildNodeView, DataTypeReader):
func_def=name_with_default_args, func_def=name_with_default_args,
query_for="sql_panel") query_for="sql_panel")
sql_header = """-- {0}: {1} sql_header = u"""-- {0}: {1}{2}
-- DROP {0} {1}; -- DROP {0} {1}{2};
""".format(object_type.upper(), header_func_name) """.format(object_type.upper(),
if hasattr(str, 'decode'): self.qtIdent(
sql_header = sql_header.decode('utf-8') self.conn,
resp_data['pronamespace'],
resp_data['proname']),
resp_data['proargtypenames'])
SQL = sql_header + func_def SQL = sql_header + func_def
SQL = re.sub('\n{2,}', '\n\n', SQL) SQL = re.sub('\n{2,}', '\n\n', SQL)

View File

@@ -606,11 +606,9 @@ class PackageView(PGChildNodeView):
sql, name = self.getSQL(gid, sid, did, result, scid) sql, name = self.getSQL(gid, sid, did, result, scid)
sql = sql.strip('\n').strip(' ') sql = sql.strip('\n').strip(' ')
sql_header = "-- Package: {}\n\n-- ".format( sql_header = u"-- Package: {}\n\n-- ".format(
self.qtIdent(self.conn, self.schema, result['name']) self.qtIdent(self.conn, self.schema, result['name'])
) )
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template( sql_header += render_template(
"/".join([self.template_path, 'delete.sql']), "/".join([self.template_path, 'delete.sql']),

View File

@@ -542,11 +542,9 @@ It may have been removed by another user or moved to another schema.
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
sql = "-- Package {}: {}".format( sql = u"-- Package {}: {}".format(
'Function' if self.node_type == 'edbfunc' else 'Procedure', 'Function' if self.node_type == 'edbfunc' else 'Procedure',
name) name)
if hasattr(str, 'decode'):
sql = sql.decode('utf-8')
if body != '': if body != '':
sql += "\n\n" sql += "\n\n"
sql += body sql += body

View File

@@ -317,11 +317,9 @@ class EdbVarView(PGChildNodeView, DataTypeReader):
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
var = res['rows'][0] var = res['rows'][0]
sql = "-- Package Variable: {}".format(var['name']) sql = u"-- Package Variable: {}".format(var['name'])
sql += "\n\n" sql += u"\n\n"
sql += "{} {};".format(var['name'], var['datatype']) sql += u"{} {};".format(var['name'], var['datatype'])
if hasattr(str, 'decode'):
sql = sql.decode('utf-8')
return ajax_response(response=sql) return ajax_response(response=sql)

View File

@@ -1732,18 +1732,15 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
except (ValueError, TypeError, KeyError): except (ValueError, TypeError, KeyError):
data[k] = v data[k] = v
try: SQL, name = self.get_sql(did, scid, tid, data)
SQL, name = self.get_sql(did, scid, tid, data) SQL = re.sub('\n{2,}', '\n\n', SQL)
SQL = re.sub('\n{2,}', '\n\n', SQL) SQL = SQL.strip('\n')
SQL = SQL.strip('\n') if SQL == '':
if SQL == '': SQL = "--modified SQL"
SQL = "--modified SQL" return make_json_response(
return make_json_response( data=SQL,
data=SQL, status=200
status=200 )
)
except Exception as e:
return internal_server_error(errormsg=str(e))
def get_index_constraint_sql(self, did, tid, data): def get_index_constraint_sql(self, did, tid, data):
""" """
@@ -2025,7 +2022,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
else: else:
return None return None
def get_exclusion_constraint_sql(self, tid, data): def get_exclusion_constraint_sql(self, did, tid, data):
""" """
Args: Args:
tid: Table ID tid: Table ID
@@ -2060,7 +2057,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
properties_sql = render_template("/".join( properties_sql = render_template("/".join(
[self.exclusion_constraint_template_path, 'properties.sql']), [self.exclusion_constraint_template_path, 'properties.sql']),
tid=tid, cid=c['oid']) did=did, tid=tid, cid=c['oid'])
status, res = self.conn.execute_dict(properties_sql) status, res = self.conn.execute_dict(properties_sql)
if not status: if not status:
return internal_server_error(errormsg=res) return internal_server_error(errormsg=res)
@@ -2097,7 +2094,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
if len(sql) > 0: if len(sql) > 0:
# Join all the sql(s) as single string # Join all the sql(s) as single string
return '\n\n'.join(sql) return u'\n\n'.join(sql)
else: else:
return None return None
@@ -2277,7 +2274,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
SQL += '\n' + check_constraint_sql SQL += '\n' + check_constraint_sql
# Check if exclusion constraint(s) is/are added/changed/deleted # Check if exclusion constraint(s) is/are added/changed/deleted
exclusion_constraint_sql = self.get_exclusion_constraint_sql(tid, data) exclusion_constraint_sql = self.get_exclusion_constraint_sql(did, tid, data)
# If we have check constraint sql then ad it in main sql # If we have check constraint sql then ad it in main sql
if exclusion_constraint_sql is not None: if exclusion_constraint_sql is not None:
SQL += '\n' + exclusion_constraint_sql SQL += '\n' + exclusion_constraint_sql
@@ -2574,9 +2571,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
# Push as string # Push as string
data['cols'] = ', '.join(cols) data['cols'] = ', '.join(cols)
sql_header = "\n-- Index: {0}\n\n-- ".format(data['name']) sql_header = u"\n-- Index: {0}\n\n-- ".format(data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template("/".join([self.index_template_path, sql_header += render_template("/".join([self.index_template_path,
'delete.sql']), 'delete.sql']),
@@ -2646,9 +2641,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
data = trigger_definition(data) data = trigger_definition(data)
sql_header = "\n-- Trigger: {0}\n\n-- ".format(data['name']) sql_header = u"\n-- Trigger: {0}\n\n-- ".format(data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template("/".join([self.trigger_template_path, sql_header += render_template("/".join([self.trigger_template_path,
'delete.sql']), 'delete.sql']),

View File

@@ -706,9 +706,7 @@ class CheckConstraintView(PGChildNodeView):
'create.sql']), 'create.sql']),
data=data) data=data)
sql_header = "-- Constraint: {0}\n\n-- ".format(data['name']) sql_header = u"-- Constraint: {0}\n\n-- ".format(data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template( sql_header += render_template(
"/".join([self.template_path, 'delete.sql']), "/".join([self.template_path, 'delete.sql']),

View File

@@ -868,9 +868,7 @@ class ExclusionConstraintView(PGChildNodeView):
SQL = render_template( SQL = render_template(
"/".join([self.template_path, 'create.sql']), data=data) "/".join([self.template_path, 'create.sql']), data=data)
sql_header = "-- Constraint: {0}\n\n-- ".format(data['name']) sql_header = u"-- Constraint: {0}\n\n-- ".format(data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template( sql_header += render_template(
"/".join([self.template_path, 'delete.sql']), "/".join([self.template_path, 'delete.sql']),

View File

@@ -918,66 +918,61 @@ class ForeignKeyConstraintView(PGChildNodeView):
Returns: Returns:
""" """
try:
SQL = render_template(
"/".join([self.template_path, 'properties.sql']),
tid=tid, conn=self.conn, cid=fkid)
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
data = res['rows'][0] SQL = render_template(
data['schema'] = self.schema "/".join([self.template_path, 'properties.sql']),
data['table'] = self.table tid=tid, conn=self.conn, cid=fkid)
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
sql = render_template("/".join([self.template_path, data = res['rows'][0]
'get_constraint_cols.sql']), data['schema'] = self.schema
tid=tid, data['table'] = self.table
keys=zip(data['confkey'], data['conkey']),
confrelid=data['confrelid'])
status, res = self.conn.execute_dict(sql) sql = render_template("/".join([self.template_path,
'get_constraint_cols.sql']),
tid=tid,
keys=zip(data['confkey'], data['conkey']),
confrelid=data['confrelid'])
if not status: status, res = self.conn.execute_dict(sql)
return internal_server_error(errormsg=res)
columns = [] if not status:
for row in res['rows']: return internal_server_error(errormsg=res)
columns.append({"local_column": row['conattname'],
"references": data['confrelid'],
"referenced": row['confattname']})
data['columns'] = columns columns = []
for row in res['rows']:
columns.append({"local_column": row['conattname'],
"references": data['confrelid'],
"referenced": row['confattname']})
SQL = render_template("/".join([self.template_path, data['columns'] = columns
'get_parent.sql']),
tid=data['columns'][0]['references'])
status, res = self.conn.execute_2darray(SQL)
if not status: SQL = render_template("/".join([self.template_path,
return internal_server_error(errormsg=res) 'get_parent.sql']),
tid=data['columns'][0]['references'])
status, res = self.conn.execute_2darray(SQL)
data['remote_schema'] = res['rows'][0]['schema'] if not status:
data['remote_table'] = res['rows'][0]['table'] return internal_server_error(errormsg=res)
SQL = render_template( data['remote_schema'] = res['rows'][0]['schema']
"/".join([self.template_path, 'create.sql']), data=data) data['remote_table'] = res['rows'][0]['table']
sql_header = "-- Constraint: {0}\n\n-- ".format(data['name']) SQL = render_template(
if hasattr(str, 'decode'): "/".join([self.template_path, 'create.sql']), data=data)
sql_header = sql_header.decode('utf-8')
sql_header += render_template( sql_header = u"-- Constraint: {0}\n\n-- ".format(data['name'])
"/".join([self.template_path, 'delete.sql']),
data=data)
sql_header += "\n"
SQL = sql_header + SQL sql_header += render_template(
"/".join([self.template_path, 'delete.sql']),
data=data)
sql_header += "\n"
return ajax_response(response=SQL) SQL = sql_header + SQL
except Exception as e: return ajax_response(response=SQL)
return internal_server_error(errormsg=str(e))
@check_precondition @check_precondition
def dependents(self, gid, sid, did, scid, tid, fkid=None): def dependents(self, gid, sid, did, scid, tid, fkid=None):

View File

@@ -873,57 +873,52 @@ class IndexConstraintView(PGChildNodeView):
Returns: Returns:
""" """
try:
SQL = render_template(
"/".join([self.template_path, 'properties.sql']),
did=did,
tid=tid,
conn=self.conn,
cid=cid,
constraint_type=self.constraint_type)
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
data = res['rows'][0] SQL = render_template(
data['schema'] = self.schema "/".join([self.template_path, 'properties.sql']),
data['table'] = self.table did=did,
tid=tid,
conn=self.conn,
cid=cid,
constraint_type=self.constraint_type)
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
sql = render_template( data = res['rows'][0]
"/".join([self.template_path, 'get_constraint_cols.sql']), data['schema'] = self.schema
cid=cid, colcnt=data['indnatts']) data['table'] = self.table
status, res = self.conn.execute_dict(sql) sql = render_template(
"/".join([self.template_path, 'get_constraint_cols.sql']),
cid=cid, colcnt=data['indnatts'])
if not status: status, res = self.conn.execute_dict(sql)
return internal_server_error(errormsg=res)
columns = [] if not status:
for row in res['rows']: return internal_server_error(errormsg=res)
columns.append({"column": row['column'].strip('"')})
data['columns'] = columns columns = []
for row in res['rows']:
columns.append({"column": row['column'].strip('"')})
SQL = render_template( data['columns'] = columns
"/".join([self.template_path, 'create.sql']),
data=data,
constraint_name=self.constraint_name)
sql_header = "-- Constraint: {0}\n\n-- ".format(data['name']) SQL = render_template(
if hasattr(str, 'decode'): "/".join([self.template_path, 'create.sql']),
sql_header = sql_header.decode('utf-8') data=data,
constraint_name=self.constraint_name)
sql_header += render_template( sql_header = u"-- Constraint: {0}\n\n-- ".format(data['name'])
"/".join([self.template_path, 'delete.sql']),
data=data)
sql_header += "\n"
SQL = sql_header + SQL sql_header += render_template(
"/".join([self.template_path, 'delete.sql']),
data=data)
sql_header += "\n"
return ajax_response(response=SQL) SQL = sql_header + SQL
except Exception as e: return ajax_response(response=SQL)
return internal_server_error(errormsg=str(e))
@check_precondition @check_precondition
def statistics(self, gid, sid, did, scid, tid, cid): def statistics(self, gid, sid, did, scid, tid, cid):

View File

@@ -839,40 +839,35 @@ class IndexesView(PGChildNodeView):
tid: Table ID tid: Table ID
idx: Index ID idx: Index ID
""" """
try:
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) SQL = render_template("/".join([self.template_path,
if not status: 'properties.sql']),
return internal_server_error(errormsg=res) did=did, tid=tid, idx=idx,
datlastsysoid=self.datlastsysoid)
data = dict(res['rows'][0]) status, res = self.conn.execute_dict(SQL)
# Adding parent into data dict, will be using it while creating sql if not status:
data['schema'] = self.schema return internal_server_error(errormsg=res)
data['table'] = self.table
# Add column details for current index data = dict(res['rows'][0])
data = self._column_details(idx, data) # Adding parent into data dict, will be using it while creating sql
data['schema'] = self.schema
data['table'] = self.table
SQL, name = self.get_sql(did, scid, tid, None, data) # Add column details for current index
data = self._column_details(idx, data)
sql_header = "-- Index: {0}\n\n-- ".format(data['name']) SQL, name = self.get_sql(did, scid, tid, None, data)
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template("/".join([self.template_path, sql_header = u"-- Index: {0}\n\n-- ".format(data['name'])
'delete.sql']),
data=data, conn=self.conn)
SQL = sql_header + '\n\n' + SQL sql_header += render_template("/".join([self.template_path,
'delete.sql']),
data=data, conn=self.conn)
return ajax_response(response=SQL) SQL = sql_header + '\n\n' + SQL
except Exception as e: return ajax_response(response=SQL)
return internal_server_error(errormsg=str(e))
@check_precondition @check_precondition
def dependents(self, gid, sid, did, scid, tid, idx): def dependents(self, gid, sid, did, scid, tid, idx):

View File

@@ -1,8 +1,8 @@
{# ============Create Rule============= #} {# ============Create Rule============= #}
{% if display_comments %} {% if display_comments %}
-- Rule: {{ data.name }} ON {{ conn|qtIdent(data.schema, data.name) }} -- Rule: {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.name) }}
-- DROP Rule {{ data.name }} ON {{ conn|qtIdent(data.schema, data.name) }}; -- DROP Rule {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.name) }};
{% endif %} {% endif %}
{% if data.name and data.schema and data.view %} {% if data.name and data.schema and data.view %}

View File

@@ -526,7 +526,7 @@ class TriggerView(PGChildNodeView):
Returns: Returns:
Formated arguments for function Formated arguments for function
""" """
formatted_args = ["'{0}'".format(arg) for arg in args] formatted_args = ["{0}".format(arg) for arg in args]
return ', '.join(formatted_args) return ', '.join(formatted_args)
@@ -889,56 +889,51 @@ class TriggerView(PGChildNodeView):
tid: Table ID tid: Table ID
trid: Trigger ID trid: Trigger ID
""" """
try:
SQL = render_template("/".join([self.template_path,
'properties.sql']),
tid=tid, trid=trid,
datlastsysoid=self.datlastsysoid)
status, res = self.conn.execute_dict(SQL) SQL = render_template("/".join([self.template_path,
if not status: 'properties.sql']),
return internal_server_error(errormsg=res) tid=tid, trid=trid,
datlastsysoid=self.datlastsysoid)
data = dict(res['rows'][0]) status, res = self.conn.execute_dict(SQL)
# Adding parent into data dict, will be using it while creating sql if not status:
data['schema'] = self.schema return internal_server_error(errormsg=res)
data['table'] = self.table
data = self.get_trigger_function_schema(data) data = dict(res['rows'][0])
# Adding parent into data dict, will be using it while creating sql
data['schema'] = self.schema
data['table'] = self.table
if len(data['custom_tgargs']) > 1: data = self.get_trigger_function_schema(data)
# We know that trigger has more than 1 argument, let's join them
data['tgargs'] = self._format_args(data['custom_tgargs'])
if len(data['tgattr']) > 1: if len(data['custom_tgargs']) > 1:
columns = ', '.join(data['tgattr'].split(' ')) # We know that trigger has more than 1 argument, let's join them
data['columns'] = self._column_details(tid, columns) data['tgargs'] = self._format_args(data['custom_tgargs'])
data = self._trigger_definition(data) if len(data['tgattr']) > 1:
columns = ', '.join(data['tgattr'].split(' '))
data['columns'] = self._column_details(tid, columns)
SQL, name = self.get_sql(scid, tid, None, data) data = self._trigger_definition(data)
sql_header = "-- Trigger: {0}\n\n-- ".format(data['name']) SQL, name = self.get_sql(scid, tid, None, data)
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template("/".join([self.template_path, sql_header = u"-- Trigger: {0}\n\n-- ".format(data['name'])
'delete.sql']),
data=data, conn=self.conn)
SQL = sql_header + '\n\n' + SQL.strip('\n') sql_header += render_template("/".join([self.template_path,
'delete.sql']),
data=data, conn=self.conn)
# If trigger is disbaled then add sql code for the same SQL = sql_header + '\n\n' + SQL.strip('\n')
if not data['is_enable_trigger']:
SQL += '\n\n'
SQL += render_template("/".join([self.template_path,
'enable_disable_trigger.sql']),
data=data, conn=self.conn)
return ajax_response(response=SQL) # If trigger is disbaled then add sql code for the same
if not data['is_enable_trigger']:
SQL += '\n\n'
SQL += render_template("/".join([self.template_path,
'enable_disable_trigger.sql']),
data=data, conn=self.conn)
except Exception as e: return ajax_response(response=SQL)
return internal_server_error(errormsg=str(e))
@check_precondition @check_precondition
def enable_disable_trigger(self, gid, sid, did, scid, tid, trid): def enable_disable_trigger(self, gid, sid, did, scid, tid, trid):

View File

@@ -1300,9 +1300,7 @@ class TypeView(PGChildNodeView, DataTypeReader):
SQL, name = self.get_sql(gid, sid, data, scid, tid=None) SQL, name = self.get_sql(gid, sid, data, scid, tid=None)
# We are appending headers here for sql panel # We are appending headers here for sql panel
sql_header = "-- Type: {0}\n\n-- ".format(data['name']) sql_header = u"-- Type: {0}\n\n-- ".format(data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
sql_header += render_template("/".join([self.template_path, sql_header += render_template("/".join([self.template_path,
'delete.sql']), 'delete.sql']),

View File

@@ -875,8 +875,8 @@ class ViewNode(PGChildNodeView, VacuumSettings):
for trigger in data['rows']: for trigger in data['rows']:
SQL = render_template("/".join( SQL = render_template("/".join(
[self.trigger_temp_path, 'sql/#{0}#/properties.sql'.format(self.manager.version)]), [self.trigger_temp_path, 'sql/#{0}#/properties.sql'.format(self.manager.version)]),
tid=trigger['oid'], tid=vid,
tgrelid=vid trid=trigger['oid']
) )
status, res = self.conn.execute_dict(SQL) status, res = self.conn.execute_dict(SQL)
@@ -894,6 +894,21 @@ class ViewNode(PGChildNodeView, VacuumSettings):
trigger['oid'], columns) trigger['oid'], columns)
res_rows = trigger_definition(res_rows) res_rows = trigger_definition(res_rows)
res_rows['schema'] = res_rows['nspname']
# It should be relname and not table, but in create.sql
# (which is referred from many places) we have used
# data.table and not data.relname so compatibility add new key as
# table in res_rows.
res_rows['table'] = res_rows['relname']
res_rows['tfunction'] = self.qtIdent(self.conn, res_rows['schema'], res_rows['tfunction'])
# Format arguments
if len(res_rows['custom_tgargs']) > 1:
formatted_args = ["{0}".format(arg) for arg in res_rows['custom_tgargs']]
res_rows['tgargs'] = ', '.join(formatted_args)
SQL = render_template("/".join( SQL = render_template("/".join(
[self.trigger_temp_path, 'sql/#{0}#/create.sql'.format(self.manager.version)]), [self.trigger_temp_path, 'sql/#{0}#/create.sql'.format(self.manager.version)]),
data=res_rows, display_comments=True) data=res_rows, display_comments=True)

View File

@@ -534,16 +534,13 @@ class TablespaceView(PGChildNodeView):
data=old_data, conn=self.conn data=old_data, conn=self.conn
) )
sql_header = """ sql_header = u"""
-- Tablespace: {0} -- Tablespace: {0}
-- DROP TABLESPACE {0}; -- DROP TABLESPACE {0};
""".format(old_data['name']) """.format(old_data['name'])
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')
SQL = sql_header + SQL SQL = sql_header + SQL
SQL = re.sub('\n{2,}', '\n\n', SQL) SQL = re.sub('\n{2,}', '\n\n', SQL)
return ajax_response(response=SQL.strip('\n')) return ajax_response(response=SQL.strip('\n'))

View File

@@ -26,7 +26,7 @@ from flask import g, current_app, session
from flask_babel import gettext from flask_babel import gettext
from flask_security import current_user from flask_security import current_user
from pgadmin.utils.crypto import decrypt from pgadmin.utils.crypto import decrypt
from psycopg2.extensions import adapt from psycopg2.extensions import adapt, encodings
import config import config
from pgadmin.model import Server, User from pgadmin.model import Server, User
@@ -37,6 +37,8 @@ from .cursor import DictCursor
if sys.version_info < (3,): if sys.version_info < (3,):
from StringIO import StringIO from StringIO import StringIO
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
else: else:
from io import StringIO from io import StringIO
@@ -62,6 +64,50 @@ psycopg2.extensions.register_type(
'TYPECAST_TO_STRING', psycopg2.STRING) 'TYPECAST_TO_STRING', psycopg2.STRING)
) )
def register_string_typecasters(connection):
if connection.encoding != 'UTF8':
# In python3 when database encoding is other than utf-8 and client
# encoding is set to UNICODE then we need to map data from database
# encoding to utf-8.
# This is required because when client encoding is set to UNICODE then
# psycopg assumes database encoding utf-8 and not the actual encoding.
# Not sure whether it's bug or feature in psycopg for python3.
if sys.version_info >= (3,):
def return_as_unicode(value, cursor):
if value is None:
return None
# Treat value as byte sequence of database encoding and then
# decode it as utf-8 to get correct unicode value.
return bytes(
value, encodings[cursor.connection.encoding]
).decode('utf-8')
unicode_type = psycopg2.extensions.new_type(
# "char", name, text, character, character varying
(19, 18, 25, 1042, 1043, 0),
'UNICODE', return_as_unicode)
else:
def return_as_unicode(value, cursor):
if value is None:
return None
# Decode it as utf-8 to get correct unicode value.
return value.decode('utf-8')
unicode_type = psycopg2.extensions.new_type(
# "char", name, text, character, character varying
(19, 18, 25, 1042, 1043, 0),
'UNICODE', return_as_unicode)
unicode_array_type = psycopg2.extensions.new_array_type(
# "char"[], name[], text[], character[], character varying[]
(1002, 1003, 1009, 1014, 1015, 0
), 'UNICODEARRAY', unicode_type)
psycopg2.extensions.register_type(unicode_type)
psycopg2.extensions.register_type(unicode_array_type)
class Connection(BaseConnection): class Connection(BaseConnection):
""" """
class Connection(object) class Connection(object)
@@ -336,6 +382,7 @@ Failed to connect to the database server(#{server_id}) for connection ({conn_id}
else: else:
self.conn.autocommit = True self.conn.autocommit = True
register_string_typecasters(self.conn)
status = _execute(cur, """ status = _execute(cur, """
SET DateStyle=ISO; SET DateStyle=ISO;
SET client_min_messages=notice; SET client_min_messages=notice;
@@ -538,11 +585,17 @@ WHERE
query: SQL query to run. query: SQL query to run.
params: Extra parameters params: Extra parameters
""" """
if sys.version_info < (3,):
if type(query) == unicode:
query = query.encode('utf-8')
else:
query = query.encode('utf-8')
cur.execute(query, params) cur.execute(query, params)
if self.async == 1: if self.async == 1:
self._wait(cur.connection) self._wait(cur.connection)
def execute_on_server_as_csv(self, query, params=None, formatted_exception_msg=False, records=2000): def execute_on_server_as_csv(self, query, params=None, formatted_exception_msg=False, records=2000):
status, cur = self.__cursor(server_cursor=True) status, cur = self.__cursor(server_cursor=True)
self.row_count = 0 self.row_count = 0
@@ -551,11 +604,14 @@ WHERE
return False, str(cur) return False, str(cur)
query_id = random.randint(1, 9999999) query_id = random.randint(1, 9999999)
if sys.version_info < (3,) and type(query) == unicode:
query = query.encode('utf-8')
current_app.logger.log(25, current_app.logger.log(25,
u"Execute (with server cursor) for server #{server_id} - {conn_id} (Query-id: {query_id}):\n{query}".format( u"Execute (with server cursor) for server #{server_id} - {conn_id} (Query-id: {query_id}):\n{query}".format(
server_id=self.manager.sid, server_id=self.manager.sid,
conn_id=self.conn_id, conn_id=self.conn_id,
query=query, query=query.decode('utf-8') if sys.version_info < (3,) else query,
query_id=query_id query_id=query_id
) )
) )
@@ -673,6 +729,13 @@ WHERE
params: extra parameters to the function params: extra parameters to the function
formatted_exception_msg: if True then function return the formatted exception message formatted_exception_msg: if True then function return the formatted exception message
""" """
if sys.version_info < (3,):
if type(query) == unicode:
query = query.encode('utf-8')
else:
query = query.encode('utf-8')
self.__async_cursor = None self.__async_cursor = None
status, cur = self.__cursor() status, cur = self.__cursor()
@@ -685,7 +748,7 @@ WHERE
u"Execute (async) for server #{server_id} - {conn_id} (Query-id: {query_id}):\n{query}".format( u"Execute (async) for server #{server_id} - {conn_id} (Query-id: {query_id}):\n{query}".format(
server_id=self.manager.sid, server_id=self.manager.sid,
conn_id=self.conn_id, conn_id=self.conn_id,
query=query, query=query.decode('utf-8'),
query_id=query_id query_id=query_id
) )
) )
@@ -703,7 +766,7 @@ Failed to execute query (execute_async) for the server #{server_id} - {conn_id}
""".format( """.format(
server_id=self.manager.sid, server_id=self.manager.sid,
conn_id=self.conn_id, conn_id=self.conn_id,
query=query, query=query.decode('utf-8'),
errmsg=errmsg, errmsg=errmsg,
query_id=query_id query_id=query_id
) )
@@ -1275,44 +1338,53 @@ Failed to reset the connection to the server due to following error:
if not formatted_msg: if not formatted_msg:
return errmsg return errmsg
errmsg += '********** Error **********\n\n' errmsg += u'********** Error **********\n\n'
if exception_obj.diag.severity is not None \ if exception_obj.diag.severity is not None \
and exception_obj.diag.message_primary is not None: and exception_obj.diag.message_primary is not None:
errmsg += exception_obj.diag.severity + ": " + \ errmsg += u"{}: {}".format(
exception_obj.diag.message_primary exception_obj.diag.severity,
exception_obj.diag.message_primary.decode('utf-8') if
hasattr(str, 'decode') else exception_obj.diag.message_primary)
elif exception_obj.diag.message_primary is not None: elif exception_obj.diag.message_primary is not None:
errmsg += exception_obj.diag.message_primary errmsg += exception_obj.diag.message_primary.decode('utf-8') if \
hasattr(str, 'decode') else exception_obj.diag.message_primary
if exception_obj.diag.sqlstate is not None: if exception_obj.diag.sqlstate is not None:
if not errmsg[:-1].endswith('\n'): if not errmsg[:-1].endswith('\n'):
errmsg += '\n' errmsg += '\n'
errmsg += gettext('SQL state: ') errmsg += gettext('SQL state: ')
errmsg += exception_obj.diag.sqlstate errmsg += exception_obj.diag.sqlstate.decode('utf-8') if \
hasattr(str, 'decode') else exception_obj.diag.sqlstate
if exception_obj.diag.message_detail is not None: if exception_obj.diag.message_detail is not None:
if not errmsg[:-1].endswith('\n'): if not errmsg[:-1].endswith('\n'):
errmsg += '\n' errmsg += '\n'
errmsg += gettext('Detail: ') errmsg += gettext('Detail: ')
errmsg += exception_obj.diag.message_detail errmsg += exception_obj.diag.message_detail.decode('utf-8') if \
hasattr(str, 'decode') else exception_obj.diag.message_detail
if exception_obj.diag.message_hint is not None: if exception_obj.diag.message_hint is not None:
if not errmsg[:-1].endswith('\n'): if not errmsg[:-1].endswith('\n'):
errmsg += '\n' errmsg += '\n'
errmsg += gettext('Hint: ') errmsg += gettext('Hint: ')
errmsg += exception_obj.diag.message_hint errmsg += exception_obj.diag.message_hint.decode('utf-8') if \
hasattr(str, 'decode') else exception_obj.diag.message_hint
if exception_obj.diag.statement_position is not None: if exception_obj.diag.statement_position is not None:
if not errmsg[:-1].endswith('\n'): if not errmsg[:-1].endswith('\n'):
errmsg += '\n' errmsg += '\n'
errmsg += gettext('Character: ') errmsg += gettext('Character: ')
errmsg += exception_obj.diag.statement_position errmsg += exception_obj.diag.statement_position.decode('utf-8') if \
hasattr(str, 'decode') else exception_obj.diag.statement_position
if exception_obj.diag.context is not None: if exception_obj.diag.context is not None:
if not errmsg[:-1].endswith('\n'): if not errmsg[:-1].endswith('\n'):
errmsg += '\n' errmsg += '\n'
errmsg += gettext('Context: ') errmsg += gettext('Context: ')
errmsg += exception_obj.diag.context errmsg += exception_obj.diag.context.decode('utf-8') if \
hasattr(str, 'decode') else exception_obj.diag.context
return errmsg return errmsg