knowledge-base/inc/tag-management
Jonathan Hodgson b84cf93f4a Adds list-tags option
This will list the tags along with the number of number of times it is
used.

An optional --noheader flag can be passed after the command to prevent
the header being printed.

e.g.

```
$ kb list-tags
name              count
----------------  -----
Linux             2
Authentication    1
Pentesting        1
Enumeration       3
Network Protocol  2
```

```
$ kb list-tags --noheader
Linux             2
Authentication    1
Pentesting        1
Enumeration       3
Network Protocol  2
```

This --noheader flag was also added to the list command

Close #10
2020-12-20 18:25:25 +00:00

83 lines
2.3 KiB
Bash

#!/usr/bin/env bash
assignTags(){
local filename
local tags
local tagIDs
local tagIDsOr
local fileID
filename="$(findFile "$1")"
[ ! -e "$filename" ] && exit 1
tags="$(cat - | sed '/^$/d')"
fileID="$(findFileId "$filename")"
# If there are tags
if [ -n "$tags" ]; then
local values
local orlist
while read -r line; do
values+=",('$(safeSQL "$line")')"
orlist+=" OR name = '$(safeSQL "$line")'"
done <<<"$(echo "$tags")"
values="$(echo "$values" | sed 's/^,//')"
orlist="$(echo "$orlist" | sed 's/^ OR //')"
# Ensure that all the tags exist
echo "INSERT INTO tags (name) VALUES $values
EXCEPT SELECT name FROM tags;" |
sqlite3 "${sqliteFile}"
# Get the tag ids we need to assosiate with the current file
tagIDs="$(echo "SELECT id FROM tags WHERE $orlist" |
sqlite3 "${sqliteFile}")"
#Loop through them all
while read -r tagID; do
tagIDsOr+=" OR tagID = $(safeSQL "$tagID")"
# Check the tag is already linkded with the file
local existing
existing="$(echo "SELECT id FROM links
WHERE itemID = $(safeSQL "$fileID")
AND tagID = $(safeSQL "$tagID")" |
sqlite3 "${sqliteFile}"
)"
# If not, add a link
if [ -z "$existing" ]; then
echo "INSERT INTO links (itemID,tagID)
VALUES ($(safeSQL "$fileID"),$(safeSQL "$tagID"))" |
sqlite3 "${sqliteFile}"
fi
done <<<"$(echo "$tagIDs")"
tagIDsOr="$(echo "$tagIDsOr" | sed 's/^ OR //')"
# Delete any links that are not in the list
echo "DELETE FROM links
WHERE itemID = $(safeSQL "$fileID")
AND NOT ( $tagIDsOr )" |
sqlite3 "${sqliteFile}"
else # If there are no tags, simply delete any that are referenced
echo "DELETE FROM links WHERE itemID = '$(safeSQL "$fileID")'" |
sqlite3 "${sqliteFile}"
fi
}
listTags(){
vecho "listTags $*"
cd "$dataDir" || return
local header="--header"
[ "$1" = "--noheader" ] && header=""
echo "SELECT tags.name,COUNT(links.id) count
FROM tags LEFT JOIN links ON tags.id = links.tagID
GROUP BY tags.id" |
sqlite3 --column $header "${sqliteFile}"
#echo "SELECT items.id,items.filename,items.title,items.type,
#GROUP_CONCAT(tags.name,',') tags
#FROM items LEFT JOIN links ON items.id = links.itemID
#LEFT JOIN tags ON links.tagID = tags.id
#GROUP BY items.id;" |
# sqlite3 --column --header "${sqliteFile}"
}