-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrebuild.sh
More file actions
executable file
·80 lines (69 loc) · 2.51 KB
/
rebuild.sh
File metadata and controls
executable file
·80 lines (69 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/bin/busybox ash
#
# Rebuild database from files.
. "${0%/*}/common.sh"
acquire_lock
echo "### DATABASE ###"
rm -f "$BACKUP_DB" "$BACKUP_DB-shm" "$BACKUP_DB-wal"
echo "1: create"
$BACKUP_BIN/init.sh --noindex
echo "2: fill files"
my_find "$BACKUP_MAIN" . $BACKUP_FIND_FILTER \( -type f -o -type l \) -name "*$BACKUP_TIME_SEP*" | sed -r "
1i .timeout 10000
1i BEGIN TRANSACTION;
s/'/''/g # duplicate single quotes
s_^([0-9]*) (.) (.*/)([^/]*)/([^/$BACKUP_TIME_SEP]*)$BACKUP_TIME_SEP([^/$BACKUP_TIME_SEP]*)_ \\
INSERT INTO history (inode, type, dirname, filename, created, deleted) VALUES \\
('\\1', '\\2', '\\3', '\\4', '\\5', '\\6');_
\$a END TRANSACTION;" | $SQLITE
echo "3: fill dirs"
# https://stackoverflow.com/a/34665012
echo "WITH RECURSIVE cte(org, parent, name, rest, pos, data1, data2) AS (
SELECT dirname, '', '.', SUBSTR(dirname,3), 0, min(created), max(deleted) FROM history
GROUP BY dirname
UNION ALL
SELECT org,
SUBSTR(org,1,pos+length(name)+1) as parent,
SUBSTR(rest,1,INSTR(rest, '/')-1) as name,
SUBSTR(rest,INSTR(rest,'/')+1) as rest,
pos+length(name)+1 as pos,
data1, data2
FROM cte
WHERE rest <> ''
)
INSERT INTO history (inode, type, dirname, filename, created, deleted)
SELECT 0, 'd', parent, name, min(data1), max(data2)
FROM cte
WHERE pos <> 0
GROUP BY parent, name;" | $SQLITE
echo "4: index"
$BACKUP_BIN/init.sh --notable
if test "$1" = "--current"; then
echo "### CURRENT ###"
rm -rf "$BACKUP_CURRENT"
# note that this simply prints fiilenames so no need to use my_find
cd "$BACKUP_MAIN"
find . $BACKUP_FIND_FILTER \( -type f -o -type l \) -name "*$BACKUP_TIME_SEP$BACKUP_TIME_NOW" | while IFS="$NL" read -r f; do
fullname="$(dirname "$f")"
mkdir -p "$BACKUP_CURRENT/$(dirname "$fullname")"
ln "$BACKUP_MAIN/$f" "$BACKUP_CURRENT/$fullname"
done
cd -> /dev/null
fi
echo "5: update dir inodes"
echo '' | $SQLITE
min_date="$(echo 'SELECT min(created) FROM history;' | $SQLITE)"
echo "min_date=$min_date"
my_find "$BACKUP_CURRENT" . $BACKUP_FIND_FILTER -type d | sed -r "
1i .timeout 10000
1i BEGIN TRANSACTION;
1i CREATE UNIQUE INDEX dirs ON history(dirname, filename) WHERE type='d';
s/'/''/g # duplicate single quotes
s@^([0-9]*) . (.*/)([^/]*)@ \\
INSERT INTO history (inode, type, dirname, filename, created, deleted) VALUES \\
('\\1', 'd', '\\2', '\\3', '$min_date', '$BACKUP_TIME_NOW') \\
ON CONFLICT(dirname, filename) WHERE type='d' DO UPDATE \\
SET inode='\\1', \\
deleted='$BACKUP_TIME_NOW';@
\$a DROP INDEX dirs;
\$a END TRANSACTION;" | $SQLITE