;;; meta-queries.lisp -- DBMS metainformation
;;;
;;; Author: Eric Marsden <eric.marsden@free.fr>
;;; Time-stamp: <2005-12-19 emarsden>
;;
;;
;; Metainformation such as the list of databases present in the
;; database management system, list of tables, attributes per table.
;; This information is not available directly, but can be deduced by
;; querying the system tables.
;;
;; Based on the queries issued by psql in response to user commands
;; `\d' and `\d tablename'; see file pgsql/src/bin/psql/psql.c


(in-package :postgresql)

(defun pg-databases (conn)
  "Return a list of the databases available at this site."
  (let ((res (pg-exec conn "SELECT datname FROM pg_database")))
    (reduce #'append (pg-result res :tuples))))

(defun pg-tables (conn)
  "Return a list of the tables present in this database."
  (let ((res (pg-exec conn "SELECT relname FROM pg_class, pg_user WHERE "
                      "(relkind = 'r') AND relname !~ '^pg_' AND usesysid = relowner ORDER BY relname")))
    (reduce #'append (pg-result res :tuples))))

(defun pg-columns (conn table)
  "Return a list of the columns present in TABLE."
  (let ((res (pg-exec conn (format nil "SELECT * FROM ~s WHERE 0 = 1" table))))
    (mapcar #'first (pg-result res :attributes))))

(defun pg-backend-version (conn)
  "Return a string identifying the version and operating environment of the backend."
  (let ((res (pg-exec conn "SELECT version()")))
    (first (pg-result res :tuple 0))))

(defun pg-describe-table (conn table)
  (flet ((oid-to-name (oid)
           (maphash (lambda (key value)
                      (when (eql value oid)
                        (return-from oid-to-name key)))
                    *type-to-oid*)))
    (let ((res (pg-exec conn (format nil "SELECT * FROM ~S WHERE 0=1" table))))
      (loop :for (name oid) :in (pg-result res :attributes)
            :collect (list name (oid-to-name oid))))))


;; EOF
