
    VhG                         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mZmZmZmZ dZ G d	 d
e      Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functiona?  
---
module: postgresql_idx
short_description: Create or drop indexes from a PostgreSQL database
description:
- Create or drop indexes from a PostgreSQL database.

options:
  idxname:
    description:
    - Name of the index to create or drop.
    type: str
    required: true
    aliases:
    - name
  login_db:
    description:
    - Name of database to connect to and where the index will be created/dropped.
    - The V(db) alias is deprecated and will be removed in version 5.0.0.
    type: str
    aliases:
    - db
  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
  schema:
    description:
    - Name of a database schema where the index will be created.
    type: str
  state:
    description:
    - Index state.
    - C(present) implies the index will be created if it does not exist.
    - C(absent) implies the index will be dropped if it exists.
    type: str
    default: present
    choices: [ absent, present ]
  table:
    description:
    - Table to create index on it.
    - Mutually exclusive with I(state=absent).
    type: str
  columns:
    description:
    - List of index columns that need to be covered by index.
    - Mutually exclusive with I(state=absent).
    type: list
    elements: str
    aliases:
    - column
  cond:
    description:
    - Index conditions.
    - Mutually exclusive with I(state=absent).
    type: str
  idxtype:
    description:
    - Index type (like btree, gist, gin, etc.).
    - Mutually exclusive with I(state=absent).
    type: str
    aliases:
    - type
  concurrent:
    description:
    - Enable or disable concurrent mode (CREATE / DROP INDEX CONCURRENTLY).
    - Pay attention, if I(concurrent=false), the table will be locked (ACCESS EXCLUSIVE) during the building process.
      For more information about the lock levels see U(https://www.postgresql.org/docs/current/explicit-locking.html).
    - If the building process was interrupted for any reason when I(cuncurrent=true), the index becomes invalid.
      In this case it should be dropped and created again.
    - Mutually exclusive with I(cascade=true).
    type: bool
    default: true
  unique:
    description:
    - Enable unique index.
    - Only btree currently supports unique indexes.
    type: bool
    default: false
    version_added: '0.2.0'
  tablespace:
    description:
    - Set a tablespace for the index.
    - Mutually exclusive with I(state=absent).
    type: str
  storage_params:
    description:
    - Storage parameters like fillfactor, vacuum_cleanup_index_scale_factor, etc.
    - Mutually exclusive with I(state=absent).
    type: list
    elements: str
  cascade:
    description:
    - Automatically drop objects that depend on the index,
      and in turn all objects that depend on those objects.
    - It used only with I(state=absent).
    - Mutually exclusive with I(concurrent=true).
    type: bool
    default: false
  trust_input:
    description:
    - If C(false), check whether values of parameters I(idxname), I(session_role),
      I(schema), I(table), I(columns), I(tablespace), I(storage_params),
      I(cond) 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'

seealso:
- module: community.postgresql.postgresql_table
- module: community.postgresql.postgresql_tablespace
- name: PostgreSQL indexes reference
  description: General information about PostgreSQL indexes.
  link: https://www.postgresql.org/docs/current/indexes.html
- name: CREATE INDEX reference
  description: Complete reference of the CREATE INDEX command documentation.
  link: https://www.postgresql.org/docs/current/sql-createindex.html
- name: ALTER INDEX reference
  description: Complete reference of the ALTER INDEX command documentation.
  link: https://www.postgresql.org/docs/current/sql-alterindex.html
- name: DROP INDEX reference
  description: Complete reference of the DROP INDEX command documentation.
  link: https://www.postgresql.org/docs/current/sql-dropindex.html

notes:
- The index building process can affect database performance.
- To avoid table locks on production databases, use I(concurrent=true) (default behavior).

attributes:
  check_mode:
    support: full

author:
- Andrew Klychkov (@Andersson007)
- Thomas O'Donnell (@andytom)

extends_documentation_fragment:
- community.postgresql.postgres
aG  
- name: Create btree index if not exists test_idx concurrently covering columns id and name of table products
  community.postgresql.postgresql_idx:
    login_db: acme
    table: products
    columns: id,name
    name: test_idx

- name: Create btree index test_idx concurrently with tablespace called ssd and storage parameter
  community.postgresql.postgresql_idx:
    login_db: acme
    table: products
    columns:
    - id
    - name
    idxname: test_idx
    tablespace: ssd
    storage_params:
    - fillfactor=90

- name: Create gist index test_gist_idx concurrently on column geo_data of table map
  community.postgresql.postgresql_idx:
    login_db: somedb
    table: map
    idxtype: gist
    columns: geo_data
    idxname: test_gist_idx

# Note: for the example below pg_trgm extension must be installed for gin_trgm_ops
- name: Create gin index gin0_idx not concurrently on column comment of table test
  community.postgresql.postgresql_idx:
    idxname: gin0_idx
    table: test
    columns: comment gin_trgm_ops
    concurrent: false
    idxtype: gin

- name: Drop btree test_idx concurrently
  community.postgresql.postgresql_idx:
    login_db: mydb
    idxname: test_idx
    state: absent

- name: Drop test_idx cascade
  community.postgresql.postgresql_idx:
    login_db: mydb
    idxname: test_idx
    state: absent
    cascade: true
    concurrent: false

- name: Create btree index test_idx concurrently on columns id,comment where column id > 1
  community.postgresql.postgresql_idx:
    login_db: mydb
    table: test
    columns: id,comment
    idxname: test_idx
    cond: id > 1

- name: Create unique btree index if not exists test_unique_idx on column name of table products
  community.postgresql.postgresql_idx:
    login_db: acme
    table: products
    columns: name
    name: test_unique_idx
    unique: true
    concurrent: false
a  
name:
  description: Index name.
  returned: success
  type: str
  sample: 'foo_idx'
state:
  description: Index state.
  returned: success
  type: str
  sample: 'present'
schema:
  description: Schema where index exists.
  returned: success
  type: str
  sample: 'public'
tablespace:
  description: Tablespace where index exists.
  returned: success
  type: str
  sample: 'ssd'
query:
  description: Query that was tried to be executed.
  returned: success
  type: str
  sample: 'CREATE INDEX CONCURRENTLY foo_idx ON test_table USING BTREE (id)'
storage_params:
  description: Index storage parameters.
  returned: success
  type: list
  sample: [ "fillfactor=90" ]
valid:
  description: Index validity.
  returned: success
  type: bool
  sample: true
)AnsibleModule)check_input)connect_to_dbensure_required_libsexec_sqlget_conn_paramspg_cursor_argspostgres_common_argument_spec)BTREEHASHGISTSPGISTGINBRINc                   4    e Zd ZdZd Zd Zd Z	 ddZd	dZy)
Indexa  Class for working with PostgreSQL indexes.

    TODO:
        1. Add possibility to change ownership
        2. Add possibility to change tablespace
        3. Add list called executed_queries (executed_query should be left too)
        4. Use self.module instead of passing arguments to the methods whenever possible

    Args:
        module (AnsibleModule) -- object of AnsibleModule class
        cursor (cursor) -- cursor object of psycopg library
        schema (str) -- name of the index schema
        name (str) -- name of the index

    Attrs:
        module (AnsibleModule) -- object of AnsibleModule class
        cursor (cursor) -- cursor object of psycopg library
        schema (str) -- name of the index schema
        name (str) -- name of the index
        exists (bool) -- flag the index exists in the DB or not
        info (dict) -- dict that contents information about the index
        executed_query (str) -- executed query
    c                     || _         |r|| _        nd| _        || _        || _        | j                   dddddg d| _        d| _        | j                          d| _        y )Npublicabsent Tnamestateschematblnametblspacevalidstorage_paramsF)r   r   modulecursorinfoexists_Index__exists_in_dbexecuted_query)selfr"   r#   r   r   s        w/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/postgresql/plugins/modules/postgresql_idx.py__init__zIndex.__init__3  sg    	 DK"DKII 
	      c                 :    | j                          | j                  S )z<Refresh index info.

        Return self.info dict.
        )r&   r$   )r(   s    r)   get_infozIndex.get_infoH  s    
 	yyr+   c           
         d}t        | || j                  | j                  dd      }|r[d| _        t	        | j                  d|d   d   |d   d	   |d   d
   r|d   d
   nd|d   d   |d   d   r|d   d   ng       | _        yd| _        y)zCheck index existence, collect info, add it to self.info dict.

        Return True if the index exists, otherwise, return False.
        a  SELECT i.schemaname, i.tablename, i.tablespace, pi.indisvalid, c.reloptions FROM pg_catalog.pg_indexes AS i JOIN pg_catalog.pg_class AS c ON i.indexname = c.relname JOIN pg_catalog.pg_index AS pi ON c.oid = pi.indexrelid WHERE i.schemaname = %(schema)s AND i.indexname = %(name)s)r   r   F)query_paramsadd_to_executedTpresentr   
schemaname	tablename
tablespacer   
indisvalid
reloptionsr   )r
   r   r   r%   dictr$   )r(   queryress      r)   __exists_in_dbzIndex.__exists_in_dbP  s    
. tUDKKQUQZQZ1[mrsDKYY1vl+A{+14Q1EQ-2!f\*7:1vl7Ks1vl3QSDI   DKr+   c	                    | j                   ry|d}d}	|r|	dz  }	|	dz  }	|r|	dz  }	|	d| j                  z  z  }	|	d| j                  d	|d
z  }	|	d|d|dz  }	|r|	d|z  z  }	|r|	d|z  z  }	|r|	d|z  z  }	|	| _        t	        | |	dd      S )a9  Create PostgreSQL index.

        Return True if success, otherwise, return False.

        Args:
            tblname (str) -- name of a table for the index
            idxtype (str) -- type of the index like BTREE, BRIN, etc
            columns (str) -- string of comma-separated columns that need to be covered by index
            tblspace (str) -- tablespace for storing the index
            storage_params (str) -- string of comma-separated storage parameters

        Kwargs:
            concurrent (bool) -- build index in concurrent mode, default True
        Fr   CREATEz UNIQUEz INDEX CONCURRENTLYz "%s"z ON ""."z" zUSING z ()z
 WITH (%s)z TABLESPACE "%s"z	 WHERE %sTreturn_boolr0   )r%   r   r   r'   r
   )
r(   r   idxtypecolumnscondr   r!   
concurrentuniquer8   s
             r)   createzIndex.createq  s      ;;?GYE_$E499$$T[['::GW55\N22E'(22E[4''E#euMMr+   c                     | j                   syd}|r|dz  }|d| j                  d| j                  dz  }|r|dz  }|| _        t	        | |dd	      S )
am  Drop PostgreSQL index.

        Return True if success, otherwise, return False.

        Args:
            schema (str) -- name of the index schema

        Kwargs:
            cascade (bool) -- automatically drop objects that depend on the index,
                default False
            concurrent (bool) -- build index in concurrent mode, default True
        Fz
DROP INDEXr=   z "r>   "z CASCADETr@   )r%   r   r   r'   r
   )r(   cascaderE   r8   s       r)   dropz
Index.drop  s]     {{_$Edii88ZE#euMMr+   N)TF)FT)	__name__
__module____qualname____doc__r*   r-   r&   rG   rK    r+   r)   r   r     s)    0!*D 8=1NfNr+   r   c                  J	   t               } | j                  t        dddg      t        ddgddddg	      t        dd
dd
g      t        dd      t        dd      t        d      t        ddg      t        dddg      t        d      t        d      t        d      t        dd      t        dd      t        d      t        dd             t        | d      }|j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  d    }	|j                  d!   }
|j                  d"   }|j                  d#   }|j                  d$   }|j                  d%   }|j                  d&   }|st        |||||||
||		       |r|r|j                  d'(       |r|r|d)k7  r|j                  d*(       |d
k(  r)|s|j                  d+(       |s2|j                  d,(       n|s|s|	s|s|
r|j                  d-|z  (       |r|dk7  r|j                  d.(       t        |       t        ||j                        }t        ||d/      \  }} |j                  d9i t        }d}t        ||||      }|j                         }d0|d1<   |j                  r|d
k(  r$|j                  rd|d2<    |j                   d9i | nz|d
k(  r$|j                  sd|d2<    |j                   d9i | nQ|dk(  r$|j                  sd|d2<    |j                   d9i | n(|dk(  r#|j                  rd|d2<    |j                   d9i | |d
k(  r|r/|j#                         t$        vr|j                  d3|d4|d5(       d6j'                  |      }|rd6j'                  |      }|j)                  ||||	|
|||      }|rM|j                         }d
|d<   |j*                  |d1<   n(|j-                  ||      }|rd|d<   |j*                  |d1<   |d7   s$|j/                          |j1                  d8|z         |s|j3                          ||d2<   |j5                           |j                   d9i | y ):NstrTr   )typerequiredaliasesdbz5.0.0zcommunity.postgresql)r   versioncollection_name)rS   rU   deprecated_aliasesr1   r   )rS   defaultchoicesbool)rS   rZ   F)rS   rS   )rS   rU   listcolumn)rS   elementsrU   )rS   r_   )idxnamelogin_dbr   rE   rF   tablerB   rC   rD   session_roler4   r!   rJ   r   trust_input)argument_specsupports_check_moder`   r   rE   rF   rb   rB   rC   rD   r4   r!   rJ   r   rc   rd   z=Concurrent mode and cascade parameters are mutually exclusive)msgbtreez,Only btree currently supports unique indexeszTable must be specifiedz%At least one column must be specifiedzIndex %s is going to be removed, so it does not make sense to pass a table name, columns, conditions, index type, or tablespacez-cascade parameter used only with state=absent)
autocommitr   r8   changedzIndex type 'z' of z is not in valid types,r    zIndex %s is invalid! ROLLBACKrP   )r   updater7   r   paramsr   	fail_jsonr	   r   r   r#   r   r   r-   
check_moder%   	exit_jsonupperVALID_IDX_TYPESjoinrG   r'   rK   rollbackwarncommitclose)re   r"   r`   r   rE   rF   rb   rB   rC   rD   r4   r!   rJ   r   rc   rd   conn_paramsdb_connectiondummyr#   rj   indexkws                          r)   mainr}     s   13M%$A54&"#9F 
 y8Y:OPVT2/%&2&58*Euu%U#%8&%0fd3+  . # F
 mmI&GMM'"E|,J]]8$FMM'"EmmI&GmmI&G== D|,J]]#34NmmI&G]]8$F==0L--.KFG\65'	6 g\]7w'1KL	!:;!HIGtw* "=?F"G H 5H$LM  !&&--8K(NM5!]!!3N3F G &&&'2E		BBwK I%,,!ByMF"r"i ByMF"r"hu||!ByMF"r"h5<< ByMF"r" 	w}}o=RY[b!cd((7# XXn5N,,ugwj.Zdflm!B#BwK..BwK **Wj1"BwK..BwKg; 3g=>ByMFrr+   __main__N)
__future__r   r   r   rS   __metaclass__DOCUMENTATIONEXAMPLESRETURNansible.module_utils.basicr   Fansible_collections.community.postgresql.plugins.module_utils.databaser   Fansible_collections.community.postgresql.plugins.module_utils.postgresr   r	   r
   r   r   r   rr   objectr   r}   rL   rP   r+   r)   <module>r      su    A @N`CJ$
L 5  EgNF gN^IX zF r+   