<?xml version="1.0" encoding="UTF-8" ?>
<!--
  ~ Copyright (c) DbVis Software AB. All Rights Reserved.
  -->

<!DOCTYPE DatabaseProfile SYSTEM "dbvis-defs.dtd">

<DatabaseProfile
        desc="Profile for PostgreSQL 7 and earlier"
        minver="9.5"
        extends="generic">

   <!-- =================================================================== -->
   <!-- Definition of the commands -->
   <!-- =================================================================== -->

   <Commands extends="true">

      <!--
        The "getTableNamesFor" command is used by Database getTableNamesFor().
        It must return table names for the catalog and schema named by
        the ${table_catalog} and ${table_catalog} variables in the first
        column.
      -->
      <Command id="postgresql.getTableNamesFor">
        <SQL>
          <![CDATA[
select TABLE_NAME
from INFORMATION_SCHEMA.TABLES
where TABLE_CATALOG = '${table_catalog}' and TABLE_SCHEMA = '${table_schema}'
order by TABLE_NAME
            ]]>
        </SQL>   
      </Command>

      <!--
        The "getColumnNamesFor" command is used by Database getColumnNamesFor().
        It must return column names for the catalog, schema and table named by
        the ${table_catalog}, ${table_catalog} and ${table_name} variables in
        the first column.
      -->
      <Command id="postgresql.getColumnNamesFor">
        <SQL>
          <![CDATA[
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_CATALOG = '${table_catalog}' and TABLE_SCHEMA = '${table_schema}'
and TABLE_NAME = '${table_name}'
order by COLUMN_NAME
            ]]>
        </SQL>   
      </Command>

      <Command id="postgresql.getCatalogs">
         <SQL>
            <![CDATA[
select * from pg_catalog.pg_database
            ]]>
         </SQL>
      </Command>

      <Command id="postgresql.getTables">
         <SQL>
            <![CDATA[
select * from pg_tables where schemaname != 'pg_catalog'
            ]]>
         </SQL>
      </Command>

      <Command id="postgresql.getTable">
         <SQL>
            <![CDATA[
select * from pg_tables where tablename = '${table}'
            ]]>
         </SQL>
      </Command>

      <!-- ================================================================= -->
      <!-- DBA related commands requiring certain privileges in the database -->
      <!-- ================================================================= -->

      <Command id="postgresql.getUsers">
         <SQL>
            <![CDATA[
select * from pg_user
            ]]>
         </SQL>
      </Command>

      <Command id="postgresql.getGroups">
         <SQL>
            <![CDATA[
select * from pg_group
            ]]>
         </SQL>
      </Command>

      <Command id="postgresql.getSettings">
         <SQL>
            <![CDATA[
select * from pg_settings
            ]]>
         </SQL>
      </Command>

      <Command id="postgresql.getSessions">
         <SQL>
            <![CDATA[
select * from pg_stat_activity
            ]]>
         </SQL>
      </Command>

      <Command id="postgresql.getLocks">
         <SQL>
            <![CDATA[
select * from pg_locks
            ]]>
         </SQL>
      </Command>

   </Commands>

   <!-- =================================================================== -->
   <!-- Definition of the object actions that are used by the tree and views -->
   <!-- =================================================================== -->

   <ObjectsActionDef extends="false">

      <ActionGroup type="Tables">
         <Action id="postgresql-tables-create-table" label="Create Table"
                 icon="add" reload="true"
                 class="tableCreateOrAlter"
                 classargs="create"/>
      </ActionGroup>

      <ActionGroup type="Table">
         <Action id="postgresql-tables-alter-table" label="Alter Table"
                 icon="edit" reload="true"
                 class="tableCreateOrAlter"
                 classargs="alter"/>

         <Action id="postgresql-table-create-index" label="Create Index" reload="true">
            <Input label="Table" style="text" editable="false">
               <Default>${objectname}</Default>
            </Input>
            <Input label="Index Name" name="indexname" style="text"/>
            <Input label="Unique" name="unique" style="check">
               <Values>unique</Values>
            </Input>

            <Input label="Columns" style="separator"/>

            <Input name="columns" style="grid">
               <Arg name="output" value='"${columnname}"${_sortorder}'/>
               <Arg name="newline" value=", "/>

               <Input name="columnname" label="Column Name" style="list">
                  <Values column="4">
                     <Command idref="getColumnNamesFor">
                        <Input name="table_catalog" value="${catalog}"/>
                        <Input name="table_schema" value="${schema}"/>
                        <Input name="table_name" value="${objectname}"/>
                     </Command>
                  </Values>
                  <Default>${0}</Default>
               </Input>
               <Input name="sortorder" label="Sort Order" style="radio">
                  <Labels>ASC|DESC|Default</Labels>
                  <Values>ASC|DESC|</Values>
                  <Default>ASC</Default>
               </Input>
               <SetVar name="_sortorder" value='#sortorder.equals("") ? "" : " " + #sortorder'/>
            </Input>

            <SetVar name="_unique" value='#unique.equals("") ? "" : " " + #unique'/>
            <SetVar name="_columns" value='#columns.trim().equals("") ? "" : "(" + #columns + ")"'/>
            <SetVar name="_indexname" value='#indexname.trim().equals("") ? "" : " \"" + #indexname + "\""'/>

            <Command>
               <SQL>
                  <![CDATA[create${_unique} index${_indexname} on "${objectname}" ${_columns}]]>
               </SQL>
            </Command>
            <Confirm>
               <![CDATA[Create index "${indexname}"?]]>
            </Confirm>
            <Result>
               <![CDATA[Index "${indexname}" created!]]>
            </Result>
         </Action>

         <Action id="postgresql-table-import-table-data" label="Import Table Data" icon="import"
                 class="tableDataImport"/>

         <Action id="postgresql-table-export" label="Export Table" icon="export"
                 class="tableExport"
                 doclink="/doclink/export-table"/>

         <Separator/>

         <Action id="postgresql-table-script" label="Script Table" icon="scriptObject"
                 class="sqlBuilder"
                 classargs="script-dialog,SELECT,SELECT *,INSERT,UPDATE,DELETE,CREATE,DROP"/>

      </ActionGroup>

      <ActionGroup type="Index">
         <Action id="postgresql-index-drop" label="Drop Index" reload="true" icon="remove">
            <Input label="Index" style="text" editable="false">
               <Default>${objectname}</Default>
            </Input>
            <Command><SQL><![CDATA[drop index ${objectname}]]></SQL></Command>
            <Confirm>
               Really drop index "${objectname}"?
            </Confirm>
            <Result>
               Index "${objectname}" dropped!
            </Result>
         </Action>
      </ActionGroup>

   </ObjectsActionDef>

   <!-- =================================================================== -->
   <!-- Definition of the database objects tree structure -->
   <!-- PostgreSQL only allows browsing default database specified in the -->
   <!-- URL. This definition simply makes non default databases  -->
   <!-- e.g catalogs as leaf nodes. -->
   <!-- All nodes below the default database is listed as owner.object -->
   <!-- =================================================================== -->

   <ObjectsTreeDef extends="false">

      <GroupNode type="Databases" label="Databases">
         <DataNode type="Catalog" label="${getCatalogs.TABLE_CAT}" drop-label-not-equal="${dbvis-defaultCatalogOrSchema}">
            <SetVar name="catalog" value="${getCatalogs.TABLE_CAT}"/>
            <Command idref="getCatalogs">
               <Filter index="TABLE_CAT" label="Name"/>
            </Command>

            <DataNode type="Tables" label="${getTableTypes.TABLE_TYPE}" is-empty-output="continue">
               <SetVar name="tableType" value="${getTableTypes.TABLE_TYPE}"/>
               <Command idref="getTableTypes"/>

               <!-- PostgreSQL 7.2 and older versions doesn't support schemas -->
               <!-- Note: The PostgresSQL driver doesn't implement            -->
               <!--       #dm.getDatabaseMajor/Minor -version ... that's why  -->
               <!--       the not so optimal use of startsWith()              -->
               <If test="#dm.getDatabaseProductVersion().startsWith('7.0') or
                         #dm.getDatabaseProductVersion().startsWith('7.1') or
                         #dm.getDatabaseProductVersion().startsWith('7.2')">
                  <DataNode type="Table" label="${getTables.TABLE_NAME}">
                     <SetVar name="objectname" value="${getTables.TABLE_NAME}"/>
                     <SetVar name="rowcount" value="true"/>
                     <SetVar name="acceptInQB" value="true"/>
                     <Command idref="getTables">
                        <Input name="catalog" value="${catalog}"/>
                        <Input name="objectname" value="%"/>
                        <Input name="tableType" value="${tableType}"/>
                     </Command>

                     <!-- Need to keep the objectname for the current table in
                       a new variable so that the viewers will be able to pick up
                       the correct input to display -->
                     <SetVar name="theTableName" value="${objectname}"/>

                     <GroupNode type="Columns" label="Columns">
                        <DataNode type="Column" label="${getColumnDefinitions.COLUMN_NAME}"
                                  label1="${getColumnDefinitions.TYPE_NAME}"
                                  isLeaf="true" 
                                  icon="#dataMap.get('getColumnDefinitions.IS_PRIMARY_KEY') eq true ? 'PrimaryKey' : 'Column'"
                                  tip="#dataMap.get('getColumnDefinitions.IS_PRIMARY_KEY') eq true ? 'This is a primary key column' : ''">
                           <SetVar name="objectname" value="${getColumnDefinitions.COLUMN_NAME}"/>
                           <Command idref="getColumnDefinitions">
                              <Input name="schema" value="${schema}"/>
                              <Input name="objectname" value="${theTableName}"/>
                              <Input name="tableType" value="Table"/>
                              <Filter index="TYPE_NAME" label="Type"/>
                           </Command>
                        </DataNode>
                     </GroupNode>

                     <GroupNode type="Indexes" label="Indexes">
                        <DataNode type="Index" label="${getIndexes.INDEX_NAME}"
                                  label1="${getIndexes.ORDINAL_POSITION}:${getIndexes.COLUMN_NAME}"
                                  isLeaf="true">
                           <SetVar name="objectname" value="${getIndexes.INDEX_NAME}"/>
                           <Command idref="getIndexes">
                              <Input name="catalog" value="${catalog}"/>
                              <Input name="objectname" value="${theTableName}"/>
                              <ProcessDataSet action="removeisnullrows" index="INDEX_NAME"/>
                           </Command>
                        </DataNode>
                     </GroupNode>
                  </DataNode>
               </If>
               <Else>
                  <DataNode type="Table" label="${getTables.TABLE_SCHEM}.${getTables.TABLE_NAME}">
                     <SetVar name="schema" value="${getTables.TABLE_SCHEM}"/>
                     <SetVar name="objectname" value="${getTables.TABLE_NAME}"/>
                     <SetVar name="rowcount" value="true"/>
                     <SetVar name="acceptInQB" value="true"/>
                     <Command idref="getTables">
                        <Input name="catalog" value="${catalog}"/>
                        <Input name="objectname" value="%"/>
                        <Input name="tableType" value="${tableType}"/>
                     </Command>

                     <!-- Need to keep the objectname for the current table in
                       a new variable so that the viewers will be able to pick up
                       the correct input to display -->
                     <SetVar name="theTableName" value="${objectname}"/>

                     <GroupNode type="Columns" label="Columns">
                        <DataNode type="Column" label="${getColumnDefinitions.COLUMN_NAME}"
                                  label1="${getColumnDefinitions.TYPE_NAME}"
                                  isLeaf="true">
                           <SetVar name="objectname" value="${getColumnDefinitions.COLUMN_NAME}"/>
                           <Command idref="getColumnDefinitions">
                              <Input name="schema" value="${schema}"/>
                              <Input name="objectname" value="${theTableName}"/>
                              <Input name="tableType" value="Table"/>
                              <Filter index="TYPE_NAME" label="Type"/>
                           </Command>
                        </DataNode>
                     </GroupNode>

                     <GroupNode type="Indexes" label="Indexes">
                        <DataNode type="Index" label="${getIndexes.INDEX_NAME}"
                                  label1="${getIndexes.ORDINAL_POSITION}:${getIndexes.COLUMN_NAME}"
                                  isLeaf="true">
                           <SetVar name="objectname" value="${getIndexes.INDEX_NAME}"/>
                           <Command idref="getIndexes">
                              <Input name="catalog" value="${catalog}"/>
                              <Input name="schema" value="${schema}"/>
                              <Input name="objectname" value="${theTableName}"/>
                              <ProcessDataSet action="removeisnullrows" index="INDEX_NAME"/>
                           </Command>
                        </DataNode>
                     </GroupNode>
                  </DataNode>
               </Else>
            </DataNode>

            <GroupNode type="Procedures" label="Functions">
               <DataNode type="Procedure" label="${getProcedures.PROCEDURE_SCHEM}.${getProcedures.PROCEDURE_NAME}" isLeaf="true">
                  <SetVar name="schema" value="${getProcedures.PROCEDURE_SCHEM}"/>
                  <SetVar name="objectname" value="${getProcedures.PROCEDURE_NAME}"/>
                  <Command idref="getProcedures">
                     <Input name="catalog" value="${catalog}"/>
                     <Input name="schema" value="${schema}"/>
                     <Filter index="PROCEDURE_NAME" label="Name"/>
                  </Command>
               </DataNode>
            </GroupNode>
         </DataNode>
      </GroupNode>

      <GroupNode type="DBA" label="DBA Views">
         <GroupNode type="Users" label="Users">
            <DataNode type="User" label="${postgresql.getUsers.usename}" isLeaf="true">
               <SetVar name="objectname" value="${postgresql.getUsers.usename}"/>
               <Command idref="postgresql.getUsers"/>
            </DataNode>
         </GroupNode>
         <GroupNode type="Groups" label="Groups">
            <DataNode type="Group" label="${postgresql.getGroups.groname}" isLeaf="true">
               <SetVar name="objectname" value="${postgresql.getGroups.groname}"/>
               <Command idref="postgresql.getGroups"/>
            </DataNode>
         </GroupNode>
         <GroupNode type="Settings" label="Settings" isLeaf="true"/>
         <GroupNode type="Locks" label="Locks" isLeaf="true"/>
         <GroupNode type="Sessions" label="Sessions" isLeaf="true"/>
      </GroupNode>

   </ObjectsTreeDef>

   <!-- =================================================================== -->
   <!-- Definition of the database objects views -->
   <!-- =================================================================== -->

   <ObjectsViewDef extends="true">

      <ObjectView type="Databases">
         <DataView id="postgresql-databases-databases" icon="Catalog" label="Databases" viewer="grid">
            <Command idref="postgresql.getCatalogs"/>
            <Message>
               <![CDATA[
<html>
List of all available databases in the database server. Only the default
database can be browsed in DbVisualizer. To browse any of the other databases
then supply the name for it in the URL during connect.
</html>
               ]]>
            </Message>
         </DataView>
      </ObjectView>

      <ObjectView type="Catalog" drop-on-condition="always"/>

      <ObjectView type="Tables">
         <DataView id="generic-tables-tables" drop-on-condition="always"/>
         <DataView id="generic-tables-references" drop-on-condition="always"/>
         
         <DataView id="postgresql-tables-tables" icon="Tables" label="Tables" viewer="grid">
            <Input name="menuItem" value="Open in New Tab...">
               <Input name="action" value="open-object-in-new-tab-command ${schema||table_schem}${object||table_name}"/>
            </Input>
            <Input name="menuItem" value="Open in Floating Tab...">
               <Input name="action" value="open-object-in-floating-tab-command ${catalog||table_schem}${object||table_name}"/>
            </Input>
            <Input name="menuItem" value="Script: SELECT ALL">
               <Input name="command" value="select * from ${schema||table_schem}${object||table_name}"/>
            </Input>
            <Input name="menuItem" value="Script: DROP TABLE">
               <Input name="command" value="drop table ${schema||table_schem}${object||table_name}"/>
            </Input>
            <Command idref="getTables">
               <Input name="catalog" value="${catalog}"/>
               <Input name="schema" value="${schema}"/>
               <Input name="objectname" value="%"/>
               <Input name="tableType" value="${tableType}"/>
            </Command>
         </DataView>
         <DataView id="postgresql-tables-references" icon="References" label="References" viewer="tables-refs">
            <Command idref="getTables">
               <Input name="catalog" value="${catalog}"/>
               <Input name="schema" value="${schema}"/>
               <Input name="objectname" value="%"/>
               <Input name="tableType" value="${tableType}"/>
            </Command>
         </DataView>
      </ObjectView>

      <ObjectView type="Table">
         <DataView id="generic-table-ddl">
            <Input name="formatSQL" value="true"/>
            <Message/>
         </DataView>
      </ObjectView>

      <!-- DBA views -->

      <ObjectView type="Users">
         <DataView id="postgresql-users-users" icon="Users" label="Users" viewer="grid">
            <Command idref="postgresql.getUsers"/>
         </DataView>
      </ObjectView>

      <ObjectView type="User">
         <DataView id="postgresql-user-info" icon="Info" label="Info" viewer="node-form"/>
      </ObjectView>

      <ObjectView type="Groups">
         <DataView id="postgresql-groups-groups" icon="Groups" label="Groups" viewer="grid">
            <Command idref="postgresql.getGroups"/>
         </DataView>
      </ObjectView>

      <ObjectView type="Group">
         <DataView id="postgresql-group-info" icon="Info" label="Info" viewer="node-form"/>
      </ObjectView>

      <ObjectView type="Settings">
         <DataView id="postgresql-settings-settings" icon="Settings" label="Settings" viewer="grid">
            <Command idref="postgresql.getSettings"/>
         </DataView>
      </ObjectView>

      <ObjectView type="Sessions">
         <DataView id="postgresql-sessions-sessions" icon="Sessions" label="Sessions" viewer="grid">
            <Command idref="postgresql.getSessions"/>
         </DataView>
      </ObjectView>

      <ObjectView type="Locks">
         <DataView id="postgresql-locks-locks" icon="Locks" label="Locks" viewer="grid">
            <Command idref="postgresql.getLocks"/>
         </DataView>
      </ObjectView>

   </ObjectsViewDef>

</DatabaseProfile>
