
    Vh                         d dl mZmZmZ eZdZdZdZd dl	m
Z
 d dlmZ d dlmZmZ d dlmZmZmZmZmZmZmZmZ d	Zd
 Zd Zd Zd Zd Z G d de      Z  G d d      Z!d Z"e#dk(  r e"        yy)    )absolute_importdivisionprint_functiona  
---
module: postgresql_publication
short_description: Add, update, or remove PostgreSQL publication
description:
- Add, update, or remove PostgreSQL publication.
options:
  name:
    description:
    - Name of the publication to add, update, or remove.
    required: true
    type: str
  login_db:
    description:
    - Name of the database to connect to and where
      the publication state will be changed.
    - The V(db) alias is deprecated and will be removed in version 5.0.0.
    aliases: [ db ]
    type: str
  columns:
    description:
    - List of tables and its columns to add to the publication.
    - If no columns are passed for table, it will be published as a whole.
    - Mutually exclusive with I(tables) and I(tables_in_schema).
    type: dict
    version_added: '3.8.0'
  rowfilters:
    description:
    - Optional dictionary of row filters to apply to I(tables) or I(columns) of the publication.
    - Mutually exclusive with I(tables_in_schema).
    type: dict
    version_added: '3.12.0'
  tables:
    description:
    - List of tables to add to the publication.
    - If no value is set all tables are targeted.
    - If the publication already exists for specific tables and I(tables) is not passed,
      nothing will be changed.
    - If you need to add all tables to the publication with the same name,
      drop existent and create new without passing I(tables).
    - Mutually exclusive with I(tables_in_schema) and I(columns).
    type: list
    elements: str
  tables_in_schema:
    description:
    - Specifies a list of schemas to add to the publication to replicate changes
      for all tables in those schemas.
    - If you want to remove all schemas, explicitly pass an empty list C([]).
    - Supported since PostgreSQL 15.
    - Mutually exclusive with I(tables) and I(columns).
    type: list
    elements: str
    version_added: '3.5.0'
  state:
    description:
    - The publication state.
    default: present
    choices: [ absent, present ]
    type: str
  parameters:
    description:
    - Dictionary with optional publication parameters.
    - Available parameters depend on PostgreSQL version.
    type: dict
  owner:
    description:
    - Publication owner.
    - If I(owner) is not defined, the owner will be set as I(login_user) or I(session_role).
    type: str
  cascade:
    description:
    - Drop publication dependencies. Has effect with I(state=absent) only.
    type: bool
    default: false
  session_role:
    description:
    - Switch to session_role after connecting. The specified session_role must
      be a role that the current login_user is a member of.
    - Permissions checking for SQL commands is carried out as though
      the session_role were the one that had logged in originally.
    type: str
    version_added: '0.2.0'
  trust_input:
    description:
    - If C(false), check whether values of parameters I(name), I(tables), I(owner),
      I(session_role), I(params) are potentially dangerous.
    - It makes sense to use C(false) only when SQL injections via the parameters are possible.
    type: bool
    default: true
    version_added: '0.2.0'
  comment:
    description:
    - Sets a comment on the publication.
    - To reset the comment, pass an empty string.
    type: str
    version_added: '3.3.0'

notes:
- PostgreSQL version must be 10 or greater.

attributes:
  check_mode:
    support: full

seealso:
- name: CREATE PUBLICATION reference
  description: Complete reference of the CREATE PUBLICATION command documentation.
  link: https://www.postgresql.org/docs/current/sql-createpublication.html
- name: ALTER PUBLICATION reference
  description: Complete reference of the ALTER PUBLICATION command documentation.
  link: https://www.postgresql.org/docs/current/sql-alterpublication.html
- name: DROP PUBLICATION reference
  description: Complete reference of the DROP PUBLICATION command documentation.
  link: https://www.postgresql.org/docs/current/sql-droppublication.html
author:
- Loic Blot (@nerzhul) <loic.blot@unix-experience.fr>
- Andrew Klychkov (@Andersson007) <andrew.a.klychkov@gmail.com>
- George Spanos (@grantanplan) <spanosgeorge@gmail.com>
extends_documentation_fragment:
- community.postgresql.postgres
a	  
- name: Create a new publication with name "acme" targeting all tables in database "test"
  community.postgresql.postgresql_publication:
    login_db: test
    name: acme
    comment: Made by Ansible

- name: Create publication "acme" publishing only prices and vehicles tables
  community.postgresql.postgresql_publication:
    name: acme
    tables:
    - prices
    - vehicles

- name: Create publication "acme" publishing only prices table and id and name from vehicles tables
  community.postgresql.postgresql_publication:
    name: acme
    columns:
      prices:
      vehicles:
        - id
        - name

- name: Create publication "acme" publishing id and name from vehicles tables, with a row filter
  community.postgresql.postgresql_publication:
    name: acme
    columns:
      vehicles:
        - id
        - name
    rowfilters:
        vehicles: (id > 100)

- name: >
    Assuming publication "acme" exists, publishing id and name from vehicles table with a
    row filter (id > 100), remove and re-add the table to the publication, with the updated row filter
  community.postgresql.postgresql_publication:
    name: acme
    columns:
      vehicles:
        - id
        - name
    rowfilters:
        vehicles: WHERE (id > 100) AND (id < 200)

- name: Create a new publication "acme" for tables in schema "myschema"
  community.postgresql.postgresql_publication:
    login_db: test
    name: acme
    tables_in_schema: myschema

- name: Remove all schemas from "acme" publication
  community.postgresql.postgresql_publication:
    login_db: test
    name: acme
    tables_in_schema: []

- name: >
    Create publication "acme", set user alice as an owner, targeting all tables
    Allowable DML operations are INSERT and UPDATE only
  community.postgresql.postgresql_publication:
    name: acme
    owner: alice
    parameters:
      publish: 'insert,update'

- name: >
    Assuming publication "acme" exists and there are targeted
    tables "prices" and "vehicles", add table "stores" to the publication
  community.postgresql.postgresql_publication:
    name: acme
    tables:
    - prices
    - vehicles
    - stores

- name: Remove publication "acme" if exists in database "test"
  community.postgresql.postgresql_publication:
    login_db: test
    name: acme
    state: absent
a  
exists:
  description:
  - Flag indicates the publication exists or not at the end of runtime.
  returned: success
  type: bool
  sample: true
queries:
  description: List of executed queries.
  returned: success
  type: str
  sample: [ 'DROP PUBLICATION "acme" CASCADE' ]
owner:
  description: Owner of the publication at the end of runtime.
  returned: if publication exists
  type: str
  sample: "alice"
tables:
  description:
  - List of tables in the publication at the end of runtime.
  - If all tables are published, returns empty list.
  returned: if publication exists
  type: list
  sample: ["\"public\".\"prices\"", "\"public\".\"vehicles\""]
alltables:
  description:
  - Flag indicates that all tables are published.
  returned: if publication exists
  type: bool
  sample: false
parameters:
  description: Publication parameters at the end of runtime.
  returned: if publication exists
  type: dict
  sample: {'publish': {'insert': false, 'delete': false, 'update': true}}
)AnsibleModule)	iteritems)check_inputpg_quote_identifier)connect_to_dbensure_required_libsexec_sqlget_conn_paramsget_server_versionpg_cursor_argspostgres_common_argument_specset_commenti'  c                 x    d| vrt        d| j                         z  d      S t        | j                         d      S )zAdd 'public.' to name of table where a schema identifier is absent
    and add quotes to each element.

    Args:
        table (str): Table name.

    Returns:
        str: Normalized table name.
    .z	public.%stable)r	   strip)r   s    /home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/postgresql/plugins/modules/postgresql_publication.pynormalize_table_namer     s7     %";#>HH"5;;='::    c                 H    t        |       D ]  \  }}t        |      | |<    | S )zAdd 'public.' to names of tables where a schema identifier is absent
    and add quotes to each element.

    Args:
        tbl_list (list): List of table names.

    Returns:
        tbl_list (list): Changed list.
    )	enumerater   )tbl_listir   s      r   transform_tables_representationr      s1     h' 25*512 Or   c                 h    i }| D ]*  }| |   rt        d | |   D              nd|t        |      <   , |S )zAdd quotes to each element of the columns list.

    Args:
        columns (dict): Dict with tables and columns.

    Returns:
        columns (dict): Changed dict.
    c              3   <   K   | ]  }|j                           y wN)r   ).0cs     r   	<genexpr>z)transform_columns_keys.<locals>.<genexpr>;  s     9\!'')9\s   N)setr   )columnsrevmap_columnsr   s      r   transform_columns_keysr'   0  sM     N y`ghm`nc9\WUZ^9\6\tx+E23y r   c                     i }t        |       D ]X  \  }}|j                         }|s|dd j                         dk(  r|dd j                         }t        |      |t	        |      <   Z |S )a2  Add quotes to each element of the rowfilters list and removes any "WHERE" clauses
    from the filter, since it's not retained in the publication `rowfilter` column

    Args:
        rowfilters (dict): Dict with tables and row filter conditions.

    Returns:
        rowfilters (dict): Changed dict.
    N   where)r   r   lower	RowFilterr   )
rowfiltersrevmap_filtersr   fltrs       r   transform_rowfilters_keysr0   @  st     N , Jtzz|BQx~~7*ABx~~':CD/N/67J r   c                     t        |       } |s| S |D cg c]  }t        |d       }}| ddj                  |      d}|S c c}w )zConvert a list of columns to a string.

    Args:
        table (str): Table name.
        columns (list): List of columns.

    Returns:
        str: String with columns.
    columnz (, ))r   r	   join)r   r%   colquoted_columns
quoted_sqls        r   pg_quote_column_listr9   U  sP     !'EDKLS)#x8LNL#TYY~%>?J Ms   Ac                   "    e Zd ZdZd Zd Zd Zy)r,   a  Represents a row filter `WHERE` clause on a particular `table`

    We overload the `==` and `!=` operators so that when comparing:
        1. any possible quoting on columns is not considered
        2. whitespace is not considered

    This makes possible to identify identical row filters and not perform any
    changes, regardless of insignificant (for Postgres) syntactic differences.
    e.g.
        '(  id > 10)' will be equivalent to '("id" > 10)'
    c                     || _         y r    )rfilter)selfr<   s     r   __init__zRowFilter.__init__u  s	    r   c                     | j                   j                  dd      j                  dd      |j                   j                  dd      j                  dd      k(  S )N"  )r<   replacer=   others     r   __eq__zRowFilter.__eq__x  sM    $$S"-55c2>%--BWBWX[]_B`BhBhilnpBqqrr   c                 &    | j                  |       S r    )rF   rD   s     r   __ne__zRowFilter.__ne__{  s    ;;u%%%r   N)__name__
__module____qualname____doc__r>   rF   rH    r   r   r,   r,   i  s    
s&r   r,   c                       e Zd ZdZd Zd Zd ZddZddZddZ	d Z
d	 Zd
 Zd Zd Zd ZddZddZddZddZddZddZddZddZddZddZy)PgPublicationa  Class to work with PostgreSQL publication.

    Args:
        module (AnsibleModule): Object of AnsibleModule class.
        cursor (cursor): Cursor object of psycopg library to work with PostgreSQL.
        name (str): The name of the publication.

    Attributes:
        module (AnsibleModule): Object of AnsibleModule class.
        cursor (cursor): Cursor object of psycopg library to work with PostgreSQL.
        name (str): Name of the publication.
        executed_queries (list): List of executed queries.
        attrs (dict): Dict with publication attributes.
        exists (bool): Flag indicates the publication exists or not.
    c                     || _         || _        || _        || _        g | _        dg i dg i i d| _        | j                         | _        y )NFrA   )	alltablestables
parametersownerschemasr%   r-   )modulecursorname
pg_srv_verexecuted_queriesattrs	check_pubexists)r=   rV   rW   rX   rY   s        r   r>   zPgPublication.__init__  sT    	$ "

 nn&r   c                 D    | j                         | _        | j                  S )z[Refresh the publication information.

        Returns:
            ``self.attrs``.
        )r\   r]   r[   )r=   s    r   get_infozPgPublication.get_info  s     nn&zzr   c                 j   | j                         }|sy|j                  d      | j                  d<   |j                  d      |j                  d      nd| j                  d<   i | j                  d   d<   |j                  dd      | j                  d   d   d	<   |j                  d
d      | j                  d   d   d<   |j                  dd      | j                  d   d   d<   |j                  d      r$|j                  d      | j                  d   d   d<   |j                  d      s| j                         }t	        |      D ]  \  }}t        |d   d      ||<    || j                  d<   | j                  dk\  r| j                         | j                  d<   | j                         }i }|D ]  }t        |d         |t        |d         <   ! || j                  d<   | j                         }i }	|D ]  }t        |d         |	t        |d         <   ! |	| j                  d<   yd| j                  d<   y)zCheck the publication and refresh ``self.attrs`` publication attribute.

        Returns:
            True if the publication with ``self.name`` exists, False otherwise.
        FpubownerrT   commentrA   rS   publish	pubinsertinsert	pubupdateupdate	pubdeletedeletepubtruncatetruncatepuballtablesschema_dot_tabler   rR   I rU   r%   	rowfilterr-   TrQ   )$_PgPublication__get_general_pub_infogetr[   #_PgPublication__get_tables_pub_infor   r	   rY   #_PgPublication__get_schema_pub_info$_PgPublication__get_columns_pub_infor$   r   '_PgPublication__get_rowfilters_pub_infor,   )
r=   pub_info
table_infor   schema_and_tablecolumn_infor%   rowfilters_infofilterss
             r   r\   zPgPublication.check_pub  sJ    ..0&ll:6

7;C<<	;R;^Y 7df

9 /1

< +8@[RW8X

< +H58@[RW8X

< +H58@[RW8X

< +H5<<&>Fll=>YDJJ|$Y/
; ||N+335J'0'< c## 34DEW4XZa b
1c $.DJJx &((,(B(B(D

9%"99;& aCMPQTU^Q_M`G05G1HIJa(/

9%#==?' iCMVWZ[fWgMhG05G1HIJi+2

<(
  '+DJJ{# r   c	                    d}	dt        | j                  d      z  g}
|r\g }|D ]1  }t        |||         }||v r|d||   z  z  }|j                  |       3 |
j                  ddj	                  |      z         n|rYg }|D ].  }t        |d      }||v r|d||   z  z  }|j                  |       0 |
j                  ddj	                  |      z         nP|r=|D cg c]  }t        |d       }}|
j                  d	dj	                  |      z         n|
j                  d
       |rOg }t        |      D ]  \  }}|j                  |d|d        |
j                  ddj	                  |      z         | j                  dj	                  |
      |      }	|r| j                  ||       |.t        | j                  |d| j                  || j                         |	S c c}w )a  Create the publication.

        Args:
            tables (list): List with names of the tables that need to be added to the publication.
            tables_in_schema (list): List of schema names of the tables that need to be added to the publication.
            params (dict): Dict contains optional publication parameters and their values.
            owner (str): Name of the publication owner.
            comment (str): Comment on the publication.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            changed (bool): True if publication has been created, otherwise False.
        TzCREATE PUBLICATION %spublication	 WHERE %szFOR TABLE %sr3   r   schemazFOR TABLES IN SCHEMA %szFOR ALL TABLES = ''z	WITH (%s)rB   
check_mode)r	   rX   r9   appendr5   r   _PgPublication__exec_sql_PgPublication__pub_set_ownerr   rW   rZ   )r=   rR   tables_in_schemar%   r-   paramsrT   rb   r   changedquery_fragmentstable_stringsr   quoted_colstbl_strr   params_listkeyvals                      r   createzPgPublication.create  s   " 25HTa5bbcM  225'%.IJ&K*U2C$CDK$$[1	2
 "">DIIm4L#LMM .-eW=J&{Z->>>G$$W-	.
 "">DIIm4L#LMTde& 3FH Eee""#<tyyIY?Z#Z[""#34K'/ =
c""#s#;<= "";;1G#GH//#((?";
/S   : >Wm		:t/D/DF 3  fs   G c	                    d}	|rF| j                   d   s6d}
|D ]  }|| j                   d   vr||   s+| j                  |      }|| j                   d   |   k7  sAd}
 nj| j                   d   |   ||   k7  rd}
 nN||   | j                   d   |   k(  sz||v s|| j                   d   v s||   | j                   d   |   k7  sd}
 n |
r| j                  |||      }	n|D ],  }|| j                   d   vs| j                  |||   ||      }	. | j                   d   D ](  }||j	                         vs| j                  ||      }	* n%|r#| j                   d   r| j                  |||      }	|r| j                   d   s|D ]  }|| j                   d   vr| j                  |||      }	)||v r||   | j                   d   |   k7  s|| j                   d   v sW||vs\| j                  ||      }	|	sr| j                  |||      }	 | j                   d   D ]  }||vs| j                  ||      }	 n|r$| j                   d   r| j                  |||      }	nZ|X|D ]'  }|| j                   d   vs| j                  ||      }	) | j                   d   D ]  }||vs| j                  ||      }	 |rt        |      D ]  \  }}| j                   d	   j                  |      r|d
k(  rr| j                   d	   d
   j                         }|j                  d      }|D ]  }||v rd||<   d||<    || j                   d	   d
   k7  s| j                  |||      }	| j                   d	   |   |k7  s| j                  |||      }	| j                  |||      }	 |r%|| j                   d   k7  r| j                  ||      }	|@|| j                   d   k7  r.t!        | j"                  |d| j$                  || j&                        }	|	S )a  Update the publication.

        Args:
            tables (list): List with names of the tables that need to be presented in the publication.
            tables_in_schema (list): List of schema names of the tables that need to be presented in the publication.
            params (dict): Dict contains optional publication parameters and their values.
            owner (str): Name of the publication owner.
            comment (str): Comment on the publication.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            changed (bool): True if publication has been updated, otherwise False.
        FrQ   rR   r%   Tr-   r   rU   rS   rc   ,rT   rb   r~   )r[   !_PgPublication__get_table_columns_PgPublication__pub_set_columns_PgPublication__pub_add_columnskeys_PgPublication__pub_drop_table_PgPublication__pub_add_table_PgPublication__pub_set_tables_PgPublication__pub_add_schema_PgPublication__pub_drop_schemar   rq   copysplit_PgPublication__pub_set_paramr   r   rW   rX   rZ   )r=   rR   r   r%   r-   r   rT   rb   r   r   need_set_columnsr   all_columnstblr   r   r   val_dictval_listvs                       r   rg   zPgPublication.update  s   "  4::k2$  

8 44 "&":":5"AK"djj&;E&BB+/(ZZ	*51WU^C'+$U^tzz)'<U'CC+ %L)A A *5 1TZZ5Me5T T+/(!$  00*Q[0\ % sEDJJx$88"&"8"8PZgq"8"rs
 "ZZ	2 VEGLLN2"&"7"7*"7"UV K0,,WjZ,XG$**[1  
_djj22"223
z2ZGj(Z_

<@XY\@]-]4::l#;;:@U #33CJ3OG"&"6"6sJS]"6"^
_ zz(+ Pf$"33CJ3OGP 

;/++FJ:+VG) + SI!66"33Fz3RGS **Y/ T!11"44V
4SGT
 %f- TS::l+//4 i'
 $(::l#;I#F#K#K#M#&99S>!) 4A H}.2.3	4 $tzz,'?	'JJ&*&:&:3PZ&:&[G L1#6#="&"6"6sCJ"6"W #223
2SG9T> Udjj11**5Z*HG7djj.C#C!$++w"&))Z9N9NPG r   c                     | j                   r_g }|j                  dt        | j                  d      z         |r|j                  d       | j	                  dj                  |      |      S y)a  Drop the publication.

        Kwargs:
            cascade (bool): Flag indicates that publication needs to be deleted
                with its dependencies.
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            changed (bool): True if publication has been updated, otherwise False.
        zDROP PUBLICATION %sr~   CASCADErB   r   N)r]   r   r	   rX   r   r5   )r=   cascader   r   s       r   dropzPgPublication.drop  sc     ;; O""#8;NtyyZg;h#hi&&y1??388O#<?TT r   c                 r    t        | dd      }|rd}nd}t        | |d| j                  id      }|r|d   S y)	zGet and return general publication information.

        Returns:
            Dict with publication information if successful, False otherwise.
        zlSELECT 1 FROM information_schema.columns WHERE table_name = 'pg_publication' AND column_name = 'pubtruncate'F)add_to_executeda  SELECT obj_description(p.oid, 'pg_publication') AS comment, r.rolname AS pubowner, p.puballtables, p.pubinsert, p.pubupdate , p.pubdelete, p.pubtruncate FROM pg_publication AS p JOIN pg_catalog.pg_roles AS r ON p.pubowner = r.oid WHERE p.pubname = %(pname)szSELECT obj_description(p.oid, 'pg_publication') AS comment, r.rolname AS pubowner, p.puballtables, p.pubinsert, p.pubupdate , p.pubdelete FROM pg_publication AS p JOIN pg_catalog.pg_roles AS r ON p.pubowner = r.oid WHERE p.pubname = %(pname)spnamequery_paramsr   r   r   rX   )r=   pgtrunc_supqueryresults       r   __get_general_pub_infoz$PgPublication.__get_general_pub_info  sY     t 'HZ_a 3E3E $Wdii4HZ_`!9r   c                 <    d}t        | |d| j                  id      S )zGet and return tables that are published by the publication.

        Returns:
            List of dicts with published tables.
        znSELECT schemaname || '.' || tablename as schema_dot_table FROM pg_publication_tables WHERE pubname = %(pname)sr   Fr   r   r=   r   s     r   __get_tables_pub_infoz#PgPublication.__get_tables_pub_info  %    He7DII2FX]^^r   c                 <    d}t        | |d| j                  id      S )zGet and return any row filters for each table that are published by the publication.

        Returns:
            List of dicts with row filters for each table.
        zSELECT schemaname || '.' || tablename as schema_dot_table, rowfilter FROM pg_publication_tables WHERE pubname = %(pname)s AND rowfilter is not NULLr   Fr   r   r   s     r   __get_rowfilters_pub_infoz'PgPublication.__get_rowfilters_pub_info  s'    G e7DII2FX]^^r   c                 <    d}t        | |d| j                  id      S )zGet and return columns that are published by the publication.

        Returns:
            List of dicts with published columns.
        zSELECT schemaname || '.' || tablename as schema_dot_table, attnames as columns FROM pg_publication_tables WHERE pubname = %(pname)sr   Fr   r   r   s     r   __get_columns_pub_infoz$PgPublication.__get_columns_pub_info  r   r   c                     d}t        | |d| j                  id      }g }|D ]!  }|j                  |j                                # |S )zhGet and return schemas added to the publication.

        Returns:
            List of schemas.
        zSELECT n.nspname FROM pg_namespace AS n JOIN pg_publication_namespace AS pn ON n.oid = pn.pnnspid JOIN pg_publication AS p ON p.oid = pn.pnpubid WHERE p.pubname = %(pname)sr   Fr   )r   rX   extendvalues)r=   r   list_of_dictslist_of_schemasds        r   __get_schema_pub_infoz#PgPublication.__get_schema_pub_info  sW    / !uGTYY;O168  	/A""188:.	/r   c                 j    d}t        | |d|id      }t        |D cg c]  }|d   	 c}      S c c}w )zaGet and return columns names of the table.

        Returns:
            Set of columns.
        zySELECT attname as column_name FROM pg_attribute WHERE attrelid = %(table)s::regclass and attnum > 0 AND NOT attisdropped;r   Fr   column_name)r   r$   )r=   r   r   r   rz   s        r   __get_table_columnsz!PgPublication.__get_table_columns
  s>    ]$We4DV[\&93C&9::9s   0c                     t        |d      }||v r|d||   z  z  }dt        | j                  d      d|}| j                  ||      S )aL  Add a table to the publication.

        Args:
            table (str): Table name.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            True if successful, False otherwise.
        r   r   ALTER PUBLICATION r~    ADD TABLE r   r	   rX   r   )r=   r   r-   r   
quoted_tblr   s         r   __pub_add_tablezPgPublication.__pub_add_table  sZ     )8
J;E)::;J8KDIIWd8e8BDu<<r   c                 t    dt        | j                  d      dt        |d      }| j                  ||      S )aO  Drop a table from the publication.

        Args:
            table (str): Table name.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            True if successful, False otherwise.
        r   r~   z DROP TABLE r   r   r   )r=   r   r   r   s       r   __pub_drop_tablezPgPublication.__pub_drop_table)  s:     :MTYYXe9f9LUT[9\^u<<r   c                     g }|D ]/  }t        |d      }||v s|d||   z  z  }|j                  |       1 dt        | j                  d      ddj                  |      }| j	                  ||      S )aq  Set a table suit that need to be published by the publication.

        Args:
            tables (list): List of tables.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            True if successful, False otherwise.
        r   r   r   r~    SET TABLE r3   r   )r	   r   rX   r5   r   )r=   rR   r-   r   quoted_tablesr   r   r   s           r   __pub_set_tableszPgPublication.__pub_set_tables:  s      	1E,UG<J
"{Z->>?
$$Z0		1
 9LDIIWd8e8<		-8PRu<<r   c                     t        ||      }||v r|d||   z  z  }dt        | j                  d      d|}| j                  ||      S )a   Add table with specific columns to the publication.
        Args:
            table (str): Table name.
            columns (list): List of columns.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            True if successful, False otherwise.
        r   r   r~   r   r   )r9   r	   rX   r   )r=   r   r%   r-   r   r   r   s          r   __pub_add_columnszPgPublication.__pub_add_columnsQ  sZ     +5':JK*U*;;<K8KDIIWd8e8CEu<<r   c                     g }t        |      D ]1  \  }}t        ||      }||v r|d||   z  z  }|j                  |       3 dt        | j                  d      ddj                  |      }| j                  ||      S )a  Set columns that need to be published by the publication.
        Args:
            columns_map (dict): Dictionary of all tables and list of columns.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            True if successful, False otherwise.
        r   r   r~   r   r3   r   )r   r9   r   r	   rX   r5   r   )	r=   columns_mapr-   r   
table_listr   r%   r   r   s	            r   __pub_set_columnszPgPublication.__pub_set_columnsc  s     
'4 	+NE7.ug>K
"j.? ?@k*		+ !M:YYz"$ 	
 u<<r   c                 t    dt        | j                  d      dt        |d      }| j                  ||      S )aP  Add a schema to the publication.

        Args:
            schema (str): Schema name.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            True if truly added, False otherwise.
        r   r~   z ADD TABLES IN SCHEMA r   r   r   r=   r   r   r   s       r   __pub_add_schemazPgPublication.__pub_add_schemaz  9     +>dii*W*=fh*OQ u<<r   c                 t    dt        | j                  d      dt        |d      }| j                  ||      S )aU  Drop a schema from the publication.

        Args:
            schema (str): Schema name.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            True if truly dropped, False otherwise.
        r   r~   z DROP TABLES IN SCHEMA r   r   r   r   s       r   __pub_drop_schemazPgPublication.__pub_drop_schema  r   r   c                 h    dt        | j                  d      d|d|d}| j                  ||      S )a  Set an optional publication parameter.

        Args:
            param (str): Name of the parameter.
            value (str): Parameter value.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            True if successful, False otherwise.
        r   r~   z SET (r   z')r   r   )r=   paramvaluer   r   s        r   __pub_set_paramzPgPublication.__pub_set_param  s4     <OtyyZg;h;@%Iu<<r   c                 b    dt        | j                  d      d|d}| j                  ||      S )av  Set a publication owner.

        Args:
            role (str): Role (user) name that needs to be set as a publication owner.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.

        Returns:
            True if successful, False otherwise.
        r   r~   z OWNER TO "r@   r   r   )r=   roler   r   s       r   __pub_set_ownerzPgPublication.__pub_set_owner  s0     %8		=$QSWYu<<r   c                 Z    |r| j                   j                  |       yt        | |d      S )a  Execute SQL query.

        Note: If we need just to get information from the database,
            we use ``exec_sql`` function directly.

        Args:
            query (str): Query that needs to be executed.

        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just add ``query`` to ``self.executed_queries`` and return True.

        Returns:
            True if successful, False otherwise.
        T)return_bool)rZ   r   r   )r=   r   r   s      r   
__exec_sqlzPgPublication.__exec_sql  s-      !!((/D%T::r   N)T)FT)F)rI   rJ   rK   rL   r>   r_   r\   r   rg   r   rp   rr   ru   rt   rs   r   r   r   r   r   r   r   r   r   r   r   rM   r   r   rO   rO     s~     '"2h?BDLU(@_	__$	;=(="=.=$=.=$=$=$=";r   rO   c                  8   t               } | j                  t        d      t        ddgddddg      t        dd	d
d	g      t        dd      t        d      t        d      t        dd      t        d      t        dd      t        dd       t        ddd       t        dd       t        dd              t        | dddg      }|j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  d   }	|j                  d    }
|j                  d!   }|j                  d"   }|j                  d#   }|	s8|sd }n"t        |      D cg c]  \  }}|d$| }}}t        |||||||
       |d
k(  r9|r|j                  d%       |r|j                  d&       |r|j                  d'       |d	k(  r|r|j                  d(       t        |       t        ||j                        }t        ||d)      \  }} |j                  d3i t        }t        |j                        }|t        k  r|j!                  d*+       ||d,k  r|j!                  d-+       |r|d,k  r|j!                  d.+       ||d,k  r|j!                  d/+       d}t#        ||||      }|rt%        |      }|rt'        |      }|rt)        |      ni }|d	k(  rT|j*                  s$|j-                  |||||||
|j.                  0      }nF|j                  |||||||
|j.                  0      }n"|d
k(  r|j1                  ||j.                  1      }i }|d	k(  s|d
k(  r|j.                  r|j3                         }n|d
k(  r|j.                  sd|_        |j5                          |j5                           |j6                  d3||j8                  |j*                  d2| y c c}}w )4NT)requiredstrdbz5.0.0zcommunity.postgresql)rX   versioncollection_name)typealiasesdeprecated_aliasespresentabsent)r   defaultchoiceslist)r   elementsdict)r   boolF)r   r   )r   r   r   )rX   login_dbstaterR   rS   rT   r   session_roletrust_inputrb   r   r%   r-   )rR   r   r%   )r-   r   )argument_specsupports_check_modemutually_exclusiverX   r   rR   rS   rT   r   r   r   rb   r   r%   r-   z = z1parameter "tables" is ignored when "state=absent"z5parameter "parameters" is ignored when "state=absent"z0parameter "owner" is ignored when "state=absent"z3parameter "cascade" is ignored when "state=present")
autocommitz3PostgreSQL server version should be 10.0 or greater)msgrn   zHPublication of tables in schema is supported by PostgreSQL 15 or greaterz?Publication of columns is supported by PostgreSQL 15 or greaterz6Row filtering is supported by PostgreSQL 15 or greaterr   )r   r   )r   queriesr]   rM   )r   rg   r   r   r   r   r   warnr   r   r
   rW   r   r   
connectionSUPPORTED_PG_VERSION	fail_jsonrO   r   r'   r0   r]   r   r   r   r_   close	exit_jsonrZ   )r   rV   rX   r   rR   r   rT   r   r   r   rb   r   r%   r-   r   kr   conn_paramsdb_connectiondummyrW   rY   r   r~   pub_fin_infos                            r   mainr    sI   13M4 54&"#9F 
 y8Y:OP%0V$&%0u%fd3%.6E4H&$/VT2'  * # E>@F == DMM'"E]]8$F]]<(FMM'"EmmI&G==0L--.KmmI&G}}%78mmI&G|,JK:CF:KL$!Q1-LKLFD&% +w	8 KKKLKKOPKKJK	gIJ  !&&--8K(NM5!]!!3N3F $F$5$56J((RS#
V(;gh:&^_*v"5UVG  jAK08(1:D*:6"J 	!!!((1A7JX^`e)0V=N=N ) PG "((1A7JX^`e)0V=N=N ) PG 
(	""7v?P?P"Q L	ex/F4E4E"++-	(	6#4#4" LLN FvWk.J.JS^SeSeviuvW Ms   P__main__N)$
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNansible.module_utils.basicr   ansible.module_utils.sixr   Fansible_collections.community.postgresql.plugins.module_utils.databaser   r	   Fansible_collections.community.postgresql.plugins.module_utils.postgresr
   r   r   r   r   r   r   r   r  r   r   r'   r0   r9   r   r,   rO   r  rI   rM   r   r   <module>r     s    A @xtQf#
L 5 .&  
  ;   *(& &,V	; V	;||w~ zF r   