s4

view s4-world.sh @ 820:e64d18e78507

Copy user_m table only when values differ
author HIROSE Yuuji <yuuji@gentei.org>
date Thu, 18 Jun 2020 19:30:06 +0900
parents d2c4c473e08e
children e9817a71f332
line source
1 #!/bin/sh
3 autoremovestop=2
5 # Setup variables for running time
6 if $isCGI; then
7 case "$S4WORLDLIST" in
8 *:*:*)
9 worldlistfile=cache/worldlist
10 worldgrpfile=cache/worldgrps
11 worldoptionfile=cache/worldoption
12 worldnamefile=cache/worldname
13 if [ ! -e $worldlistfile -o $worldlistfile -ot s4-config.sh \
14 -o ! -e $worldoptionfile -o $worldoptionfile -ot s4-config.sh \
15 -o s4-world.sh -nt $worldoptionfile ]
16 then
17 echo S4MASTERURL=$S4MASTERURL >> tmp/debug.out
18 cat <<-EOF > $worldlistfile
19 <div><table>
20 <tr><th>World List</th></tr>
21 <tr><td title="Base World$nl拠点となるWorldです">&rArr;
22 <a href="${S4MASTERURL:-$URL}">Base</a></td></tr>
23 EOF
24 true > $worldoptionfile
25 for i in $S4WORLDLIST; do
26 echo $i | {
27 IFS=: read name short d
28 cgi="s4-world-$short$cgiext"
29 conf="s4-config-$short.sh"
30 cat<<-EOF >>$worldlistfile
31 <tr><td title="$d">&rArr; <a href="$cgi">$name</a></td></tr>
32 EOF
33 cat<<-EOF >>$worldoptionfile
34 <option title="$d" value="$conf">$name</option>
35 EOF
36 echo "$name" > $worldnamefile.$short
37 }
38 done
39 if [ -s "$worldoptionfile" ]; then
40 echo "<option value=\"s4-config.sh\">Base</option>" >> $worldoptionfile
41 echo "</table>$nl</div>" >> $worldlistfile
42 sed 's/href="\([^>]*\)"/href="\1?grps"/' $worldlistfile \
43 > $worldgrpfile
44 else
45 true > $worldoptionfile; true > $worldlistfile # Remove contents
46 rm -f ${worldnamefile}.*
47 fi
48 fi
49 if [ -s "$worldlistfile" ]; then
50 S4WORLDS="▼spaste(\`$worldlistfile')"
51 S4WORLDNAME=${S4WORLD:+`cat $worldnamefile.$S4WORLD`}
52 S4WORLDGRPS="▼spaste(\`$worldgrpfile')"
53 fi
54 ;;
55 esac
56 fi
59 syncaccount_1() {
61 n_m=`query "SELECT printf('%d:%d',\
62 (SELECT count(*) FROM m.user), \
63 (SELECT count(*) FROM user));"`
64 n=${n_m%:*}; m=${n_m#*:} # n:m
65 if [ -z "$n" -o "$n" -lt 2 ]; then
66 err "Skipping account sync because m.user cannot be reached[n=$n]."
67 return -3
68 fi
69 if [ -z "$forceusersync" -a ! -f db/forceusersync ]; then
70 if [ $((m-n)) -le $((autoremovestop+0)) ]; then
71 # If if-condition evaluation fails, fall through to else-caluse
72 rm -f db/forceusersync
73 else
74 err "More than $autoremovestop users vanished($((m-n)))."
75 err "Automatic removal canceled. If you want to sync user accounts"
76 err "forcibly, touch db/forceusersync file each time of world update."
77 return -4
78 fi
79 fi
80 err "`gdate +%S.%3N` Starting account synchronization[$$]"
82 ## num=$(sqlite3 -bail -cmd 'PRAGMA FOREIGN_KEYS=on' $db <<EOF
83 num=$(query <<EOF
84 BEGIN;
85 DElETE FROM main.user WHERE rowid NOT IN (SELECT rowid FROM m.user);
86 INSERT INTO main.user(rowid, name)
87 SELECT rowid, name FROM m.user
88 WHERE m.user.rowid NOT IN (SELECT rowid FROM user);
89 UPDATE user SET name = (SELECT name FROM m.user WHERE main.user.rowid=m.user.rowid);
90 DELETE FROM main.user_s WHERE rowid NOT IN (SELECT rowid FROM m.user_s);
91 REPLACE INTO main.user_s(rowid, name, key, type, val, bin)
92 SELECT rowid,* FROM m.user_s;
93 DELETE FROM main.user_m WHERE rowid NOT IN (SELECT rowid FROM m.user_m);
94 REPLACE INTO main.user_m(rowid, name, key, type, val, bin)
95 SELECT rowid,* FROM m.user_m
96 WHERE user_m.name != m.user_m.name
97 OR user_m.key != m.user_m.key
98 OR user_m.type != m.user_m.type
99 OR user_m.val != m.user_m.val
100 OR length(user_m.bin)!= length(m.user_m.bin)
101 ;
102 END;
104 /* Compare user tables */
105 WITH master AS (
106 SELECT p.rowid,* FROM m.user p
107 NATURAL LEFT JOIN m.user_s
108 NATURAL LEFT JOIN m.user_m
109 ), thisworld AS (
110 SELECT p.rowid,* FROM user p
111 NATURAL LEFT JOIN user_s
112 NATURAL LEFT JOIN user_m
113 ), m_a AS (
114 SELECT * FROM master EXCEPT SELECT * FROM thisworld
115 ), a_m AS (
116 SELECT * FROM thisworld EXCEPT SELECT * FROM master
117 ) SELECT (SELECT count(*) FROM m_a) + (SELECT count(*) FROM a_m);
118 EOF
119 )
120 if [ -n "$num" -a "$num" -eq 0 ]; then
121 err "`gdate +%S.%3N` Account synchronization[$$] done in difference $num"
122 echo "`date '+%F %T'`: Sync done by process $$" >> $syncflag
123 else
124 err "Account synch[$$] failed or bailed with num=[$num]"
125 fi
126 return $num
127 }
129 syncaccount() {
130 forceusersync=$1
131 err "db=$db mas=$S4MASTERDB sessdb=$sessdb"
132 # If in parent world, no need to do rest of jobs
133 if [ -z "$S4MASTERDB" -o ! -s "$S4MASTERDB" ]; then
134 return
135 fi
136 # Confim child
137 if [ "$db" -ef "$S4MASTERDB" ]; then
138 return # Points to the same file
139 fi
140 # File based sync check precedes to DB count check for performance issue
141 syncflag=${db%.*}.synctime
142 runflag=${db%.*}.run
143 userupdateflag=`dirname $S4MASTERDB`/`basename $userupdateflag`
144 test ! -e "$userupdateflag" && return
145 [ -z "$forceusersync" -a "$syncflag" -nt "$userupdateflag" ] && return
146 if [ -s "$runflag" ]; then
147 limit=`cat $runflag|tr -c -d 0-9`
148 if [ -n "$limit" -a "$limit" -gt `date +%s` ]; then
149 err "World $S4WORLD account sync withholded by process $$"
150 return # Running sync by other process not leaching timeout
151 fi
152 fi
153 echo $((`date +%s` + 10)) > $runflag # Setting running flag by timeout 10s
154 query<<-EOF
155 .bail ON
156 ATTACH DATABASE "$S4MASTERDB" AS m;
157 EOF
158 syncaccount_1
159 rc=$?
160 test -e "$runflag" && rm -f "$runflag"
161 query<<-EOF
162 DETACH DATABASE m;
163 .bail OFF
164 EOF
165 return $rc
166 }