commit 330cb9da36651b701085ad53ae75ff296d02202a
parent 5f458f58aa782ee09febc9643fa8741cb8750727
Author: Hubert depesz Lubaczewski <depesz@depesz.com>
Date: Thu, 23 Nov 2023 14:12:52 +0100
Add list-dependencies-from-patches.awk
Tool provided by Jan Pobříslo (ccx).
Also, fix markdown in readme.
Diffstat:
3 files changed, 64 insertions(+), 8 deletions(-)
diff --git a/CHANGES b/CHANGES
@@ -1,3 +1,7 @@
+2023-11-23 :
+- Added tools/list-dependencies-from-patches.awk to list dependencies on
+ POSIX systems without Bash. Provided by Jan Pobříslo (ccx)
+
2017-08-07 :
- Added functions to assert that user (loading patch) is either superuser, or
is not superuser, or is one of listed users.
diff --git a/README.md b/README.md
@@ -20,7 +20,7 @@ To install versioning simply run install.versioning.sql in your database
# USAGE
In your files with patches to database, put whole logic in single
-transaction, and use \_v.\* functions - usually \_v.register_patch() at
+transaction, and use \_v.\* functions - usually \_v.register\_patch() at
least to make sure everything is OK.
For example. Let's assume you have patch files:
@@ -63,7 +63,7 @@ This will make sure that patch 001-users can only be applied after
# AVAILABLE FUNCTIONS
-## \_v.register_patch( TEXT, TEXT[], TEXT[] )
+## \_v.register\_patch( TEXT, TEXT[], TEXT[] )
Registers named patch (first argument), checking if all required patches (2nd
argument) are installed, and that no conflicting patches (3rd argument) are
@@ -71,37 +71,50 @@ installed.
2nd and 3rd arguments default to NULL/empty array.
-## \_v.try_register_patch( TEXT, TEXT[], TEXT[] )
+## \_v.try\_register\_patch( TEXT, TEXT[], TEXT[] )
-Works just like \_v.register_patch(), but instead of raising exception it
+Works just like \_v.register\_patch(), but instead of raising exception it
returns true if it worked, and false if it didn't.
-## \_v.unregister_patch( TEXT )
+## \_v.unregister\_patch( TEXT )
Removes information about given patch from the versioning data.
It doesn't remove objects that were created by this patch - just removes
metainformation.
-## \_v.assert_user_is_superuser()
+## \_v.assert\_user\_is\_superuser()
Make sure that current patch is being loaded by superuser.
If it's not - it will raise exception, and break transaction.
-## \_v.assert_user_is_not_superuser()
+## \_v.assert\_user\_is\_not\_superuser()
Make sure that current patch is not being loaded by superuser.
If it is - it will raise exception, and break transaction.
-## \_v.assert_user_is_one_of(TEXT, TEXT, ... )
+## \_v.assert\_user\_is\_one\_of(TEXT, TEXT, ... )
Make sure that current patch is being loaded by one of listed users.
If ```current_user``` is not listed as one of arguments - function will raise
exception and break the transaction.
+# ADDITIONAL TOOLS
+
+## list-dependencies-from-patches.sh
+
+Helper script that scans given filenames for versioning function calls, and
+extracts dependency tree in a way that allows for sorting it using
+[tsort](https://www.man7.org/linux/man-pages/man1/tsort.1.html).
+
+## list-dependencies-from-patches.awk
+
+Implementation of the dependency listing tool, in awk, without depending on
+Bash. Provided by Jan Pobříslo (ccx).
+
# SUPPORT
If you'd like to suggest new functionality or ask anything - please use
diff --git a/tools/list-dependencies-from-patches.awk b/tools/list-dependencies-from-patches.awk
@@ -0,0 +1,39 @@
+#!/bin/awk -f
+
+# Simple tool to list dependencies in form suitable for tsort utility.
+# Run this script like this:
+# /some/path/list-dependencies-from-patches.awk *.sql | tsort | tac
+# To get patches in order that satisfies dependencies while loading them.
+
+tolower($0) ~ /^[[:space:]]*select[[:space:]]+_v.register_patch\(/ {
+ if(!match($0, /\([[:space:]]*'/)) {
+ print "warning: malformed register_patch line: "FILENAME":"FNR >"/dev/stderr"
+ print "no patch name found" >"/dev/stderr"
+ next
+ }
+ line_remaining = substr($0, RSTART + RLENGTH)
+
+ if(!match(line_remaining, /'/)) {
+ print "warning: malformed register_patch line: "FILENAME":"FNR >"/dev/stderr"
+ print "not end of patch name" >"/dev/stderr"
+ next
+ }
+ patch_name = substr(line_remaining, 1, RSTART - 1)
+ line_remaining = substr(line_remaining, RSTART + RLENGTH)
+
+ print patch_name " " patch_name;
+ if(!match(line_remaining, /[[:space:]]*,[[:space:]]*ARRAY\[[[:space:]]*'/)) {
+ next
+ }
+ line_remaining = substr(line_remaining, RSTART + RLENGTH)
+ while(match(line_remaining, /[[:space:]]*,[[:space:]]*ARRAY\[[[:space:]]*'/)) {
+ print patch_name " " substr(line_remaining, 1, RSTART - 1)
+ line_remaining = substr(line_remaining, RSTART + RLENGTH)
+ }
+ if(!match(line_remaining, /'/)) {
+ print "warning: malformed register_patch line: "FILENAME":"FNR >"/dev/stderr"
+ print "not end of dependency name" >"/dev/stderr"
+ next
+ }
+ print patch_name " " substr(line_remaining, 1, RSTART - 1)
+}