comment lib/database/update (#LLM-assisted - Claude)

This commit is contained in:
Vincent Riquer 2026-04-05 19:28:45 +02:00
parent 006555c53e
commit 4b1ba6bf7a

View File

@ -1,11 +1,33 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright © 2012-2026 ScriptFanix
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of the GNU General Public License v3 is includded in the LICENSE file
# at the root of the project.
updateTags() { updateTags() {
local reader \ local reader \
# Build a WHERE clause fragment that excludes files already read by any
# known reader version; files not matching any known version need a
# re-read
for reader in "${tagreaders[@]}" for reader in "${tagreaders[@]}"
do do
tagreaderclause+="${tagreaderclause:+ AND }NOT tags.tagreader = \"$reader\"" tagreaderclause+="${tagreaderclause:+ AND }NOT tags.tagreader = \"$reader\""
done done
# Query source files that need tag updates: either the file's
# last_change differs from the stored tag row's last_change, or the
# tagreader version has changed.
# Only files linked to a destination with action=1 (transcode) are
# included.
echo ' echo '
SELECT DISTINCT SELECT DISTINCT
source_files.id, source_files.id,
@ -48,11 +70,13 @@ updateTags() {
) )
AND mime_type_actions.action = 1 AND mime_type_actions.action = 1
ORDER BY source_files.id' >&3 ORDER BY source_files.id' >&3
# Optionally cap the number of files processed in one run
(( maxbatch )) && echo "LIMIT $maxbatch" >&3 (( maxbatch )) && echo "LIMIT $maxbatch" >&3
echo ' echo '
; ;
SELECT "AtOM:NoMoreFiles";' >&3 SELECT "AtOM:NoMoreFiles";' >&3
# Collect all result rows; sentinel "AtOM:NoMoreFiles" ends the loop
read -u4 -r -d $'\0' line read -u4 -r -d $'\0' line
while ! [[ $line = AtOM:NoMoreFiles ]] while ! [[ $line = AtOM:NoMoreFiles ]]
do do
@ -60,9 +84,10 @@ echo '
(( filecount++ )) (( filecount++ ))
read -u4 -r -d $'\0' line read -u4 -r -d $'\0' line
done done
echo 'BEGIN TRANSACTION;' >&3 # Wrap all updates in a transaction echo 'BEGIN TRANSACTION;' >&3
for line in "${tagfiles[@]}" for line in "${tagfiles[@]}"
do do
# Split each row on the ::AtOM:SQL:Sep:: column separator
sourcefileid=${line%%::AtOM:SQL:Sep::*} sourcefileid=${line%%::AtOM:SQL:Sep::*}
rest=${line#*::AtOM:SQL:Sep::} rest=${line#*::AtOM:SQL:Sep::}
lastchange=${rest%%::AtOM:SQL:Sep::*} lastchange=${rest%%::AtOM:SQL:Sep::*}
@ -107,7 +132,9 @@ echo '
rest=${rest#*::AtOM:SQL:Sep::} rest=${rest#*::AtOM:SQL:Sep::}
oldbitrate=${rest%%::AtOM:SQL:Sep::*} oldbitrate=${rest%%::AtOM:SQL:Sep::*}
((++count)) ((++count))
# Show percentage progress in interactive mode
(( cron )) || echo -en "\rTags: $((count*100/filecount))%" (( cron )) || echo -en "\rTags: $((count*100/filecount))%"
# Commit every 100 files: limit reprocessing on interrupt/crash
if (( count % 100 == 0 )) if (( count % 100 == 0 ))
then then
echo 'COMMIT;BEGIN TRANSACTION;' >&3 echo 'COMMIT;BEGIN TRANSACTION;' >&3
@ -116,6 +143,10 @@ echo '
fi fi
if getTags if getTags
then then
# Set a dirty flag for each field that changed since
# the last read;
# only changed fields will be included in the UPDATE
# statement below
[[ $oldalbum != "$album" ]]&& ual=1 [[ $oldalbum != "$album" ]]&& ual=1
[[ $oldalbumartist != "$albumartist" ]]&&uaa=1 [[ $oldalbumartist != "$albumartist" ]]&&uaa=1
[[ $oldartist != "$artist" ]]&& uar=1 [[ $oldartist != "$artist" ]]&& uar=1
@ -133,6 +164,13 @@ echo '
[[ $oldrate != "$rate" ]]&& ura=1 [[ $oldrate != "$rate" ]]&& ura=1
[[ $oldchannels != "$channels" ]]&& uch=1 [[ $oldchannels != "$channels" ]]&& uch=1
[[ $oldbitrate != "$bitrate" ]]&& ubi=1 [[ $oldbitrate != "$bitrate" ]]&& ubi=1
# Emit an Update with only dirty columns plus
# last_change/tagreader.
# ::AtOM:FT:: prefix forces text quoting even for
# numeric-looking values.
# Absent values become SQL NULL (no quotes).
# Each ${flag:+col val} expands to nothing when the
# flag is unset.
Update tags \ Update tags \
${ual:+album "${album:+::AtOM:FT::}${album:-NULL}"}\ ${ual:+album "${album:+::AtOM:FT::}${album:-NULL}"}\
${uaa:+albumartist "${albumartist:+::AtOM:FT::}${albumartist:-NULL}"}\ ${uaa:+albumartist "${albumartist:+::AtOM:FT::}${albumartist:-NULL}"}\
@ -156,6 +194,8 @@ echo '
${ubi:+bitrate "${bitrate:-NULL}"} \ ${ubi:+bitrate "${bitrate:-NULL}"} \
tagreader "$tagreader" \ tagreader "$tagreader" \
>/dev/null <<<"source_file = $sourcefileid" >/dev/null <<<"source_file = $sourcefileid"
# Clear all tag variables and dirty flags for the next
# iteration
unset genre \ unset genre \
albumartist \ albumartist \
year \ year \
@ -212,6 +252,7 @@ echo '
ubi ubi
fi fi
done done
# Commit the final partial batch
echo 'COMMIT;' >&3 echo 'COMMIT;' >&3
(( cron )) || echo -n $'\r' (( cron )) || echo -n $'\r'
(( count )) && echo -n "Read tags from $count files." (( count )) && echo -n "Read tags from $count files."