postgres.py: add query_params (#64661)

* postgres.py: add query_params

* postgres.py: add query_params, add changelog
This commit is contained in:
Andrey Klychkov 2019-11-15 10:07:56 +03:00 committed by John R Barker
parent 8ff6e4c68e
commit 01e4e1bb42
3 changed files with 35 additions and 9 deletions

View file

@ -0,0 +1,3 @@
bugfixes:
- postgres.py - add a new keyword argument ``query_params`` (https://github.com/ansible/ansible/pull/64661).
- postgresql_idx.py - use the ``query_params`` arg of exec_sql function (https://github.com/ansible/ansible/pull/64661).

View file

@ -122,7 +122,7 @@ def connect_to_db(module, conn_params, autocommit=False, fail_on_conn=True):
return db_connection return db_connection
def exec_sql(obj, query, ddl=False, add_to_executed=True): def exec_sql(obj, query, query_params=None, ddl=False, add_to_executed=True, dont_exec=False):
"""Execute SQL. """Execute SQL.
Auxiliary function for PostgreSQL user classes. Auxiliary function for PostgreSQL user classes.
@ -130,21 +130,43 @@ def exec_sql(obj, query, ddl=False, add_to_executed=True):
Returns a query result if possible or True/False if ddl=True arg was passed. Returns a query result if possible or True/False if ddl=True arg was passed.
It necessary for statements that don't return any result (like DDL queries). It necessary for statements that don't return any result (like DDL queries).
Arguments: Args:
obj (obj) -- must be an object of a user class. obj (obj) -- must be an object of a user class.
The object must have module (AnsibleModule class object) and The object must have module (AnsibleModule class object) and
cursor (psycopg cursor object) attributes cursor (psycopg cursor object) attributes
query (str) -- SQL query to execute query (str) -- SQL query to execute
Kwargs:
query_params (dict or tuple) -- Query parameters to prevent SQL injections,
could be a dict or tuple
ddl (bool) -- must return True or False instead of rows (typical for DDL queries) ddl (bool) -- must return True or False instead of rows (typical for DDL queries)
(default False) (default False)
add_to_executed (bool) -- append the query to obj.executed_queries attribute add_to_executed (bool) -- append the query to obj.executed_queries attribute
dont_exec (bool) -- used with add_to_executed=True to generate a query, add it
to obj.executed_queries list and return True (default False)
""" """
try:
obj.cursor.execute(query)
if dont_exec:
# This is usually needed to return queries in check_mode
# without execution
query = obj.cursor.mogrify(query, query_params)
if add_to_executed: if add_to_executed:
obj.executed_queries.append(query) obj.executed_queries.append(query)
return True
try:
if query_params is not None:
obj.cursor.execute(query, query_params)
else:
obj.cursor.execute(query)
if add_to_executed:
if query_params is not None:
obj.executed_queries.append(obj.cursor.mogrify(query, query_params))
else:
obj.executed_queries.append(query)
if not ddl: if not ddl:
res = obj.cursor.fetchall() res = obj.cursor.fetchall()
return res return res

View file

@ -334,10 +334,11 @@ class Index(object):
Return index statistics dictionary if index exists, otherwise False. Return index statistics dictionary if index exists, otherwise False.
""" """
query = ("SELECT * FROM pg_stat_user_indexes " query = ("SELECT * FROM pg_stat_user_indexes "
"WHERE indexrelname = '%s' " "WHERE indexrelname = %(name)s "
"AND schemaname = '%s'" % (self.name, self.schema)) "AND schemaname = %(schema)s")
result = exec_sql(self, query, add_to_executed=False) result = exec_sql(self, query, query_params={'name': self.name, 'schema': self.schema},
add_to_executed=False)
if result: if result:
return [dict(row) for row in result] return [dict(row) for row in result]
else: else:
@ -355,9 +356,9 @@ class Index(object):
"ON i.indexname = c.relname " "ON i.indexname = c.relname "
"JOIN pg_catalog.pg_index AS pi " "JOIN pg_catalog.pg_index AS pi "
"ON c.oid = pi.indexrelid " "ON c.oid = pi.indexrelid "
"WHERE i.indexname = '%s'" % self.name) "WHERE i.indexname = %(name)s")
res = exec_sql(self, query, add_to_executed=False) res = exec_sql(self, query, query_params={'name': self.name}, add_to_executed=False)
if res: if res:
self.exists = True self.exists = True
self.info = dict( self.info = dict(