From Wroclaw hackfest, Nov 2010

Problem

Database core functions and plugins are scattered throughout the interface, and several functions are redundant.

Decisions

  • add a Database menu
  • move all DB-related stuff there
    • exception: Add and create DB layers can stay in the Layer menu, at least for now (we'll discuss about this in the ML)
  • reduce redundancy by combining as much as possible separate commands into common frameworks

Open Questions

  • PostGIS Manager vs SPIT: the aim is putting PGM in trunk, and drop SPIT. This requires:
    • adding a mass import facility to PGM
    • adding shp2pgsql (and eventually pgsql2shp) to the QGIS package
  • Integrate PGM with RT SQL Layer, with RT Extractor as an option
  • Drop redundant plugins, integrating their strengths into one of the main functions

Tool analysis

Core functionalities

  • Add vector layer. Enables to load a new layer from a database through OGR library. Support for ODBC, ESRI GeoDB, OGDI, PG, MySQL is present. The interface presents a connexion manager enabling to create, edit and delete connexions.
  • Add PostGIS Layer.This is QGIS native PostGIS support. The interface presents :
    • a connexion manager
    • a list of schemas and tables
    • a query builder helper
    • a table searching interface
    • saving and loading connexions
  • Add spatialite layer. Spatialite native support. Same interface as postgis layer, without the query builder and connexion save/load functionality.
  • New spatialite layer. Interface to create a new layer in an existing or new spatialite db. DDL creation helpers.
  • Offline Editing (a plugin, now in trunk)

Plugin functionalities

General purpose

  • DB Manager. Aims at being the final solution. Currently missing features:
    1. versioning (from PostGIS Manager)
    2. geometry processing (from PostGIS Manager)
    3. GUI to import/export data (from PostGIS Manager)
    4. GUI to import QGIS layer from the canvas (from QSpatialite)
    5. run just a part of a query (selected with the mouse) (from PostGIS Query editor)
    6. import PostGIS raster (from WKTRaster, but going through GDAL)
    7. import of multiple shapefiles (as in SPIT)
    8. query builder (from RT_Sql_Layer)
    9. query manager (from RT_Sql_Layer)
    10. keep the history in the SQL window (new)
Possibly redundant:
  • Fast SQL Layer (Pablo Carreira): docked SQL window with syntax highlight
  • Custom DB Query Plugin (Ricardo Garcia Silva): very similar to RT Sql Layer
  • PgQuery for PostGIS (Gerry James). Enables to create postgis table from a given query. Unclear what are its strengths over others.
    • open/save query file
    • run/save/clear query
    • add dataset to qgis
    • output query to table
    • list tables
  • PostGIS Query editor (Horst Duester). Uses a shapefile and pgsql2shp to save the query result and load it to qgis. Its main advantage over RT SQL Layer is its ability to work on keyless tables.
    • load / save queries
To be incorporated in DB Manager?
  • WKTRaster (Mauricio de Paulo). Adds rasters form a PostGIS database (Note: pg rasters can be added through GDAL, no additional software needed for this)
  • PostGIS Manager (Martin Dobias). This is a feature-loaded database management with a pgadmin look & feel. For shp import it requires shp2pgsql (a major limitation in some OS)
    • query execution
    • import of data
    • visualisation of DB objects
    • admin tasks (vacuum, empty/delete/edit ddl)
    • geometry processing (to new field of db)
    • table versioning
    • preview of data
  • QSpatiaLite (Romain Rivière)
  • SpatiaLite manager (Faunalia). This is a tool very similar to DB manager, but still incomplete, for spatialite data; raster support is missing. Will be removed soon
  • RT Sql Layer (Faunalia). This is another tool for DB management, based on DB manager. Note: it is recalled from RT_Extractor, this should be fixed before deprecating it
    • DB explorer
    • query builder (open/load previous, query helpers : from, returns, where, column retriever)
    • adds result of query as in-memory layer
  • SPIT (core). Shapefile to PostGIS importer. Old, to be deprecated in favour of DB Manager when this last will be able to import multiple shapefiles
    • connexion manager
    • import options
    • editable list of shapefiles to import

Special uses

  • pgVersion
  • Linear Referencing System. Works on PostGIS only.
  • RT Postgres Extractor. Exports geometry based on layer.
  • Export to MySQL
  • MongoDBLayer
  • terralibpglayer

Additional suggestions

from Vincent:

I think now it's time to refactor all those plugins into one or a few DB
management tool, with a specific menu entry and no duplicate functionalities.

I think we can distinguish a set of main functionalities :
  1. DB connexion manager
  2. * with all DB connexions, whatever their type
  3. DB explorer / manager
  4. * Used as advanced database management. It would refactor spatialite manager, DB manager and RT SQL Layer manager
  5. adding layer from DB connexion
  6. *This would refactor Add spatialite layer, add postgis layer and adding layer from query which can be found in the various plugins.

Put a plugin into "Database" menu

This cap. describes how to put a python plugin into the Database menu.
For a C++ plugin you must adapt the code to follow the C++ rules.

Consider that self.iface maintains the QgsInterface instance, PostGIS is the name of the submenu you want create and self.action stores a QAction which recalls your plugin. You can use the following code snippets to add/remove the plugin to/from the Database menu:

 #add to Database menu
 self.iface.addPluginToDatabaseMenu("&PostGIS", self.action)
 #remove from Database menu
 self.iface.removePluginDatabaseMenu("&PostGIS", self.action)

If you want that your python plugin works also with previous QGis version (< 1.7),
you must use the following code snippets instead:

 #add to Database menu
 if hasattr(self.iface, "addPluginToDatabaseMenu"):
     self.iface.addPluginToDatabaseMenu("&PostGIS", self.action)
 else:
     self.iface.addPluginToMenu("&PostGIS", self.action)
 #remove from Database menu
 if hasattr(self.iface, "removePluginDatabaseMenu"):
     self.iface.removePluginDatabaseMenu("&PostGIS", self.action)
 else:

self.iface.removePluginMenu("&PostGIS", self.action)