Skip to content

Commit

Permalink
SchemaSpy can be run on the entire database, as well as on the curren…
Browse files Browse the repository at this point in the history
…t table
  • Loading branch information
emarsden committed Aug 22, 2024
1 parent 9b67fcf commit eb415f6
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 18 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## [0.13] - Unreleased

- Display JSONB columns in the same was as JSON columns.
- Display JSONB columns in the same way as JSON columns.

- In a row-list buffer, display meta-information on any table indexes under the column
metainformation.
Expand All @@ -21,6 +21,9 @@
arguments: the cell-value, max-width, table. This functionality can be used to display BYTEA
columns as inline images, for example.

- The SchemaSpy functionality has been extended to allow the application to be run on the entire
database, displaying a graphical representation of the relations between tables.


## [0.12] - 2024-08-06

Expand Down
Binary file added doc/src/img/screenshot-schemaspy-database.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 22 additions & 7 deletions doc/src/schemaspy.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
# Running SchemaSpy

In a row-list buffer, type `S` to run the [SchemaSpy application](https://schemaspy.org/) on the
current table and view the diagram of the table structure in a dedicated buffer. This functionality
only works in graphical mode (not in the terminal) and requires your Emacs to support SVG images;
PGmacs will inform you if these conditions are not met.
The [SchemaSpy application](https://schemaspy.org/) is able to generate useful illustrations
documenting the tables present in a database, the links between them and their schema structure.
PGmacs includes functionality to run SchemaSpy on the database and table you are viewing, and
display the relevant images in an Emacs buffer. This functionality only works in graphical mode (not
in the terminal) and requires your Emacs to support SVG images; PGmacs will inform you if these
conditions are not met.

In the main table-list buffer, type `S` to run SchemaSpy on the current database and display the
relationships between the tables in a dedicated buffer.

![Screenshot table](img/screenshot-schemaspy-table.png)

In a row-list buffer, type `S` to run SchemaSpy the on the current table and view the table
structure diagram in a dedicated buffer.

![Screenshot table](img/screenshot-schemaspy-table.png)

Expand All @@ -22,7 +32,7 @@ dependencies are preinstalled. The container image is around 380MB in size.

```shell
podman run -v %D:/output --network=host docker.io/schemaspy/schemaspy:latest -t pgsql11 -host %h
-port %P -u %u -p %p -db %d -s %s -i %t -imageformat svg
-port %P -u %u -p %p -db %d -imageformat svg
```

Some notes on customizing this commandline:
Expand All @@ -37,7 +47,12 @@ Some notes on customizing this commandline:
PostgreSQL is running, `%P` by the port it is running on, `%u` by the user, `%p` by the PostgreSQL
password for that user, `%s` by the current table schema name, `%t` by the current table name and
`%D` by the directory (which will be created in the system temporary directory) in which output
files are created by SchemaSpy.
files are created by SchemaSpy. The `%s` and `%t` values are only used in the table view, and not in
the database view, and are added automatically to the commandline in the form

```
-s %s -i %t
```


## Running SchemaSpy installed locally
Expand All @@ -46,7 +61,7 @@ You can also run the SchemaSpy java application natively, using a setting for
`pgmacs-schemaspy-cmdline` similar to the following:

```shell
java -jar ~/lib/schemaspy.jar -dp /usr/share/java/postgresql-jdbc4.jar -t pgsql11 -host %h -port %P -u %u -p %p -db %d -s %s -i %t -imageformat svg -o /tmp/schema
java -jar ~/lib/schemaspy.jar -dp /usr/share/java/postgresql-jdbc4.jar -t pgsql11 -host %h -port %P -u %u -p %p -db %d -imageformat svg -o /tmp/schema
```

This requires the following software to be installed:
Expand Down
66 changes: 56 additions & 10 deletions pgmacs.el
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,21 @@ PostgreSQL over a slow network link."
;; - JDBC support for PostgreSQL (here in /usr/share/java/postgresql-jdbc4.jar, installable for example
;; using "sudo apt install libpostgresql-jdbc-java")
(defcustom pgmacs-schemaspy-cmdline
;; "podman run -v %D:/output --network=host docker.io/schemaspy/schemaspy:latest -t pgsql11 -host %h -port %P -u %u -p %p -db %d -s %s -i %t -imageformat svg"
"java -jar ~/lib/schemaspy.jar -dp /usr/share/java/postgresql-jdbc4.jar -t pgsql11 -host %h -port %P -u %u -p %p -db %d -s %s -i %t -imageformat svg -o %D"
"Commandline for running the SchemaSpy application or software container.
"podman run -v %D:/output --network=host docker.io/schemaspy/schemaspy:latest -t pgsql11 -host %h -port %P -u %u -p %p -db %d -imageformat svg"
"Commandline for running the SchemaSpy application or container.
SchemaSpy can be run as a Java application installed on the local
machine, or (probably easier for most users) in a Docker/Podman
software container that contains the necessary dependencies.
In this commandline, %d is replaced by the database name, %h by
the hostname on which PostgreSQL is running, %P by the port it is
running on, %u by the user, %p by the password, %s by the current
table schema name, %t by the current table name and %D by the
directory (which will be created in the system temporary
directory) in which output files are created by SchemaSpy."
directory) in which output files are created by SchemaSpy. The %s
and %t values will only be used when generating illustrations
concerning a specific table, rather than the entire database."
:type 'string
:group 'pgmacs)

Expand Down Expand Up @@ -1495,6 +1501,7 @@ Table names are schema-qualified if the schema is non-default."
(shw "e" "New buffer with output from SQL query")
(shw "E" "Run SQL from a buffer and display the output")
(shw "<number>" "Move point to nth column")
(shw "S" "Run SchemaSpy on the current table and display the SVG output")
(shw "<" "Move point to the first row in the table")
(shw ">" "Move point to the last row in the table")
(shw "{" "Shrink the horizontal space used by the current column")
Expand Down Expand Up @@ -2125,6 +2132,7 @@ Uses PostgreSQL connection CON."
(shw "p" "New buffer listing the functions and procedures in the current database")
(shw "e" "New buffer with output from SQL query")
(shw "E" "Run buffer SQL and display the output")
(shw "S" "Run SchemaSpy on the current database and display the SVG output")
(shw "<" "Go to the first table in the table list")
(shw ">" "Go to the last table in the table list")
(shw "{" "Shrink the horizontal space used by the current column")
Expand Down Expand Up @@ -2156,6 +2164,46 @@ Uses PostgreSQL connection CON."
(table-name (if (pg-qualified-name-p pgmacs--table)
(pg-qualified-name-name pgmacs--table)
pgmacs--table)))
(when (eql :local (cl-first ci))
(message "Replacing Unix connection by network connection to localhost for SchemaSpy"))
(let* ((cmdline (concat pgmacs-schemaspy-cmdline
" -s %s -i %t"))
(cmd (cl-multiple-value-bind (type host port dbname user password) ci
(let ((spec (list (cons ?h (if (eq type :local) "localhost" host))
(cons ?P (or port 5432))
(cons ?d dbname)
(cons ?u user)
(cons ?p password)
(cons ?s schema-name)
(cons ?t table-name)
(cons ?D schemaspy-dir))))
(format-spec cmdline spec))))
(out (format "%s/diagrams/tables/%s.1degree.svg"
schemaspy-dir
table-name)))
(message "Running cmd %s, output to %s" cmd out)
(shell-command cmd)
(when (file-exists-p out)
(find-file out))))))

;; Run SchemaSpy on the current database, display the SVG. We display only the "real relationships"
;; summary SVG for the database; SchemaSpy generates many other images including for each orphan
;; table.
(defun pgmacs--schemaspy-database (&rest _ignore)
(interactive)
(unless (display-graphic-p)
(error "SchemaSpy will only work on a graphical terminal"))
(unless (image-type-available-p 'svg)
(error "SchemaSpy support needs SVG support in your Emacs"))
(let* ((tmpdir (temporary-file-directory))
(schemaspy-dir (expand-file-name "pgmacs-schemaspy" tmpdir)))
(when (file-directory-p schemaspy-dir)
(delete-directory schemaspy-dir t))
;; The Docker image for schemaspy runs as user "java" for an obscure reason, so ensure that the
;; temporary schemaspy-dir is writable for all.
(with-file-modes #o777
(make-directory schemaspy-dir t))
(let ((ci (pgcon-connect-info pgmacs--con)))
(when (eql :local (cl-first ci))
(message "Replacing Unix connection by network connection to localhost for SchemaSpy"))
(let ((cmd (cl-multiple-value-bind (type host port dbname user password) ci
Expand All @@ -2164,18 +2212,15 @@ Uses PostgreSQL connection CON."
(cons ?d dbname)
(cons ?u user)
(cons ?p password)
(cons ?s schema-name)
(cons ?t table-name)
(cons ?D schemaspy-dir))))
(format-spec pgmacs-schemaspy-cmdline spec))))
(out (format "%s/diagrams/tables/%s.1degree.svg"
schemaspy-dir
table-name)))
(format-spec pgmacs-schemaspy-db-cmdline spec))))
(out (format "%s/diagrams/summary/relationships.real.compact.svg" schemaspy-dir)))
(message "Running cmd %s, output to %s" cmd out)
(shell-command cmd)
(when (file-exists-p out)
(find-file out))))))


;;;###autoload
(defun pgmacs-open (con)
"Browse the contents of PostgreSQL database to which we are connected over CON."
Expand Down Expand Up @@ -2227,6 +2272,7 @@ Uses PostgreSQL connection CON."
"?" pgmacs--table-list-help
"RET" pgmacs--table-list-RET
"<deletechar>" pgmacs--table-list-delete
"S" pgmacs--schemaspy-database
"r" pgmacs--table-list-rename
"g" pgmacs--table-list-redraw
"o" pgmacs-open-table
Expand Down

0 comments on commit eb415f6

Please sign in to comment.