s4

annotate s4-world.sh @ 966:679f621de4b5

Remove forceusersync file for safety
author HIROSE Yuuji <yuuji@gentei.org>
date Sun, 20 Feb 2022 15:59:32 +0900
parents b6d1384e1b2c
children
rev   line source
yuuji@734 1 #!/bin/sh
yuuji@734 2
yuuji@817 3 autoremovestop=2
yuuji@817 4
yuuji@791 5 # Setup variables for running time
yuuji@791 6 if $isCGI; then
yuuji@791 7 case "$S4WORLDLIST" in
yuuji@791 8 *:*:*)
yuuji@791 9 worldlistfile=cache/worldlist
yuuji@797 10 worldgrpfile=cache/worldgrps
yuuji@791 11 worldoptionfile=cache/worldoption
yuuji@791 12 worldnamefile=cache/worldname
yuuji@791 13 if [ ! -e $worldlistfile -o $worldlistfile -ot s4-config.sh \
yuuji@791 14 -o ! -e $worldoptionfile -o $worldoptionfile -ot s4-config.sh \
yuuji@794 15 -o s4-world.sh -nt $worldoptionfile ]
yuuji@791 16 then
yuuji@791 17 echo S4MASTERURL=$S4MASTERURL >> tmp/debug.out
yuuji@791 18 cat <<-EOF > $worldlistfile
yuuji@797 19 <div><table>
yuuji@791 20 <tr><th>World List</th></tr>
yuuji@794 21 <tr><td title="Base World$nl拠点となるWorldです">&rArr;
yuuji@794 22 <a href="${S4MASTERURL:-$URL}">Base</a></td></tr>
yuuji@791 23 EOF
yuuji@791 24 true > $worldoptionfile
yuuji@791 25 for i in $S4WORLDLIST; do
yuuji@791 26 echo $i | {
yuuji@791 27 IFS=: read name short d
yuuji@791 28 cgi="s4-world-$short$cgiext"
yuuji@791 29 conf="s4-config-$short.sh"
yuuji@791 30 cat<<-EOF >>$worldlistfile
yuuji@791 31 <tr><td title="$d">&rArr; <a href="$cgi">$name</a></td></tr>
yuuji@791 32 EOF
yuuji@791 33 cat<<-EOF >>$worldoptionfile
yuuji@791 34 <option title="$d" value="$conf">$name</option>
yuuji@791 35 EOF
yuuji@791 36 echo "$name" > $worldnamefile.$short
yuuji@791 37 }
yuuji@791 38 done
yuuji@791 39 if [ -s "$worldoptionfile" ]; then
yuuji@791 40 echo "<option value=\"s4-config.sh\">Base</option>" >> $worldoptionfile
yuuji@791 41 echo "</table>$nl</div>" >> $worldlistfile
yuuji@797 42 sed 's/href="\([^>]*\)"/href="\1?grps"/' $worldlistfile \
yuuji@797 43 > $worldgrpfile
yuuji@791 44 else
yuuji@791 45 true > $worldoptionfile; true > $worldlistfile # Remove contents
yuuji@791 46 rm -f ${worldnamefile}.*
yuuji@791 47 fi
yuuji@791 48 fi
yuuji@791 49 if [ -s "$worldlistfile" ]; then
yuuji@797 50 S4WORLDS="▼spaste(\`$worldlistfile')"
yuuji@791 51 S4WORLDNAME=${S4WORLD:+`cat $worldnamefile.$S4WORLD`}
yuuji@797 52 S4WORLDGRPS="▼spaste(\`$worldgrpfile')"
yuuji@791 53 fi
yuuji@791 54 ;;
yuuji@791 55 esac
yuuji@791 56 fi
yuuji@791 57
yuuji@734 58
yuuji@817 59 syncaccount_1() {
yuuji@817 60
yuuji@817 61 n_m=`query "SELECT printf('%d:%d',\
yuuji@817 62 (SELECT count(*) FROM m.user), \
yuuji@817 63 (SELECT count(*) FROM user));"`
yuuji@817 64 n=${n_m%:*}; m=${n_m#*:} # n:m
yuuji@817 65 if [ -z "$n" -o "$n" -lt 2 ]; then
yuuji@817 66 err "Skipping account sync because m.user cannot be reached[n=$n]."
yuuji@817 67 return -3
yuuji@794 68 fi
yuuji@817 69 if [ -z "$forceusersync" -a ! -f db/forceusersync ]; then
yuuji@817 70 if [ $((m-n)) -le $((autoremovestop+0)) ]; then
yuuji@817 71 # If if-condition evaluation fails, fall through to else-caluse
yuuji@817 72 rm -f db/forceusersync
yuuji@817 73 else
yuuji@817 74 err "More than $autoremovestop users vanished($((m-n)))."
yuuji@817 75 err "Automatic removal canceled. If you want to sync user accounts"
yuuji@817 76 err "forcibly, touch db/forceusersync file each time of world update."
yuuji@817 77 return -4
yuuji@817 78 fi
yuuji@966 79 else
yuuji@966 80 rm -f db/forceusersync # Remove flag file for future
yuuji@817 81 fi
yuuji@885 82 err "`gdate +%S.%3N` Starting account synchronization"
yuuji@887 83 SYNC_M=1
yuuji@742 84
yuuji@965 85 if [ -s "$syncflag" ]; then
yuuji@965 86 prevsync=`tail -1 $syncflag|colrm 20` # 2020-06-21 12:30:00 = 19cols
yuuji@965 87 else
yuuji@965 88 prevsync="2000-01-01 00:00:00"
yuuji@965 89 fi
yuuji@835 90 syncall=${db%.*}.syncall
yuuji@835 91 err syncallfile=$syncall
yuuji@835 92 if [ -e $syncall ]; then
yuuji@835 93 rm -f "$syncall"
yuuji@835 94 err "Force update user_m for all users"
yuuji@835 95 else
yuuji@835 96 case "$prevsync" in
yuuji@835 97 [2-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]\ [012][0-9]:??:??)
yuuji@881 98 SYNCCOND="WHERE name in (SELECT name FROM m.user_s WHERE key='profupdate' AND val > '$prevsync')"
yuuji@880 99 err "prevsync=$prevsync"
yuuji@880 100 limited=`query "SELECT DISTINCT name FROM m.user_s $SYNCCOND;"`
yuuji@880 101 if [ -n "$limited" ]; then
yuuji@880 102 err synccond limited to "$limited"
yuuji@880 103 else
yuuji@880 104 err synccond canceled for user_m
yuuji@880 105 SYNCCOND="WHERE NULL"
yuuji@887 106 SYNC_M=
yuuji@880 107 fi
yuuji@835 108 err "Touch $syncall (owner=`id -un`) to update all user_m."
yuuji@835 109 ;;
yuuji@835 110 *)
yuuji@835 111 echo arere ;;
yuuji@835 112 esac
yuuji@835 113 fi
yuuji@817 114 ## num=$(sqlite3 -bail -cmd 'PRAGMA FOREIGN_KEYS=on' $db <<EOF
yuuji@903 115 result=$(query <<EOF
yuuji@734 116 BEGIN;
yuuji@734 117 DElETE FROM main.user WHERE rowid NOT IN (SELECT rowid FROM m.user);
yuuji@734 118 INSERT INTO main.user(rowid, name)
yuuji@734 119 SELECT rowid, name FROM m.user
yuuji@734 120 WHERE m.user.rowid NOT IN (SELECT rowid FROM user);
yuuji@904 121 /* PrimaryKey:name cannot be changed, but ensure the integrity of user */
yuuji@904 122 UPDATE user SET name = (SELECT name FROM m.user WHERE main.user.rowid=m.user.rowid) WHERE name != (SELECT name from m.user WHERE main.user.rowid=m.user.rowid);
yuuji@742 123 DELETE FROM main.user_s WHERE rowid NOT IN (SELECT rowid FROM m.user_s);
yuuji@742 124 REPLACE INTO main.user_s(rowid, name, key, type, val, bin)
yuuji@734 125 SELECT rowid,* FROM m.user_s;
yuuji@887 126 ${SYNC_M:+
yuuji@742 127 DELETE FROM main.user_m WHERE rowid NOT IN (SELECT rowid FROM m.user_m);
yuuji@742 128 REPLACE INTO main.user_m(rowid, name, key, type, val, bin)
yuuji@835 129 SELECT rowid,* FROM m.user_m $SYNCCOND
yuuji@834 130 EXCEPT
yuuji@835 131 SELECT rowid,* FROM main.user_m $SYNCCOND
yuuji@887 132 ;} /* SYNC_M closed here */
yuuji@903 133 SELECT 'OK';
yuuji@734 134 END;
yuuji@903 135 EOF
yuuji@903 136 )
yuuji@903 137 err "`gdate +%S.%3N` Update account tables finished with result=[$result]"
yuuji@903 138 test x"$result" = x"OK" && num=$(query <<EOF
yuuji@734 139 /* Compare user tables */
yuuji@734 140 WITH master AS (
yuuji@734 141 SELECT p.rowid,* FROM m.user p
yuuji@887 142 NATURAL LEFT JOIN m.user_s
yuuji@887 143 ${SYNC_M:+ NATURAL LEFT JOIN m.user_m}
yuuji@903 144 $SYNCCOND
yuuji@743 145 ), thisworld AS (
yuuji@734 146 SELECT p.rowid,* FROM user p
yuuji@887 147 NATURAL LEFT JOIN user_s
yuuji@887 148 ${SYNC_M:+ NATURAL LEFT JOIN user_m}
yuuji@903 149 $SYNCCOND
yuuji@734 150 ), m_a AS (
yuuji@743 151 SELECT * FROM master EXCEPT SELECT * FROM thisworld
yuuji@734 152 ), a_m AS (
yuuji@743 153 SELECT * FROM thisworld EXCEPT SELECT * FROM master
yuuji@734 154 ) SELECT (SELECT count(*) FROM m_a) + (SELECT count(*) FROM a_m);
yuuji@734 155 EOF
yuuji@817 156 )
yuuji@817 157 if [ -n "$num" -a "$num" -eq 0 ]; then
yuuji@885 158 err "`gdate +%S.%3N` Account synchronization done in difference $num"
yuuji@817 159 echo "`date '+%F %T'`: Sync done by process $$" >> $syncflag
yuuji@817 160 else
yuuji@885 161 err "Account synch failed or bailed with num=[$num]"
yuuji@817 162 fi
yuuji@817 163 return $num
yuuji@817 164 }
yuuji@817 165
yuuji@817 166 syncaccount() {
yuuji@817 167 forceusersync=$1
yuuji@859 168 ## err "db=$db mas=$S4MASTERDB sessdb=$sessdb"
yuuji@817 169 # If in parent world, no need to do rest of jobs
yuuji@817 170 if [ -z "$S4MASTERDB" -o ! -s "$S4MASTERDB" ]; then
yuuji@817 171 return
yuuji@817 172 fi
yuuji@817 173 # Confim child
yuuji@817 174 if [ "$db" -ef "$S4MASTERDB" ]; then
yuuji@817 175 return # Points to the same file
yuuji@817 176 fi
yuuji@817 177 # File based sync check precedes to DB count check for performance issue
yuuji@817 178 syncflag=${db%.*}.synctime
yuuji@817 179 runflag=${db%.*}.run
yuuji@817 180 userupdateflag=`dirname $S4MASTERDB`/`basename $userupdateflag`
yuuji@817 181 test ! -e "$userupdateflag" && return
yuuji@965 182 [ -z "$forceusersync" -a -f "$syncflag" -a \
yuuji@965 183 "$syncflag" -nt "$userupdateflag" ] && return
yuuji@817 184 if [ -s "$runflag" ]; then
yuuji@817 185 limit=`cat $runflag|tr -c -d 0-9`
yuuji@892 186 err syncaccount: limit=$limit
yuuji@817 187 if [ -n "$limit" -a "$limit" -gt `date +%s` ]; then
yuuji@817 188 err "World $S4WORLD account sync withholded by process $$"
yuuji@817 189 return # Running sync by other process not leaching timeout
yuuji@817 190 fi
yuuji@817 191 fi
yuuji@817 192 echo $((`date +%s` + 10)) > $runflag # Setting running flag by timeout 10s
yuuji@892 193 err syncaccount: setrunflag[$runflag]=`cat $runflag`
yuuji@817 194 query<<-EOF
yuuji@817 195 .bail ON
yuuji@817 196 ATTACH DATABASE "$S4MASTERDB" AS m;
yuuji@817 197 EOF
yuuji@817 198 syncaccount_1
yuuji@817 199 rc=$?
yuuji@817 200 test -e "$runflag" && rm -f "$runflag"
yuuji@817 201 query<<-EOF
yuuji@817 202 DETACH DATABASE m;
yuuji@817 203 .bail OFF
yuuji@817 204 EOF
yuuji@817 205 return $rc
yuuji@817 206 }
yuuji@825 207
yuuji@825 208 getworldDB() { # $1=conf
yuuji@825 209 (unset DB; . "$1"; echo ${DB:-$defaultdb})
yuuji@825 210 }
yuuji@825 211
yuuji@825 212 worldnameDBlist() {
yuuji@825 213 echo Base:Base:`getworldDB ./s4-config.sh`
yuuji@825 214 for w in $S4WORLDLIST; do
yuuji@825 215 case "$w" in
yuuji@825 216 *:*:*:*) continue ;;
yuuji@825 217 *:*:*) w=${w%:*}; name=${w%:*}; world=${w#*:} ;;
yuuji@825 218 *) continue ;;
yuuji@825 219 esac
yuuji@825 220 d=`getworldDB "./s4-config-$world.sh"`
yuuji@825 221 test -s "$d" && echo ${world}:${name}:$d
yuuji@825 222 done
yuuji@825 223 }
yuuji@825 224
yuuji@828 225 grepgrpworld() {
yuuji@828 226 world=$1; wname=$2; exp=$3; tdb=$4
yuuji@825 227 case $world in
yuuji@827 228 Base) cgi=${S4MASTERURL:-$URL} ;;
yuuji@825 229 *) cgi=s4-world-$world$cgiext ;;
yuuji@825 230 esac
yuuji@827 231 case $exp in
yuuji@828 232 mem:*)
yuuji@828 233 arg=${exp#*:}
yuuji@828 234 cond="user = '$arg'"
yuuji@828 235 guide="「${S4WORLDNAME:-Base}」以外の世界の所属グループ"
yuuji@828 236 s="(<a href=\"$cgi?stage=grps&kwd=mem:$arg\">所属絞</a>)" ;;
yuuji@828 237 *)
yuuji@828 238 arg=`sqlquote "%$3%"`
yuuji@828 239 cond="gname LIKE $arg"
yuuji@828 240 guide="$exp を含むグループは別世界にもあります"
yuuji@828 241 s="(<a href=\"$cgi?stage=grps&kwd=$exp\">絞込</a>)" ;;
yuuji@827 242 esac
yuuji@825 243 query <<-EOF |
yuuji@828 244 ATTACH DATABASE "$tdb" AS td;
yuuji@825 245 SELECT DISTINCT td.grp.rowid,hex(gname)
yuuji@825 246 FROM td.grp NATURAL JOIN td.grp_mem
yuuji@825 247 WHERE $cond;
yuuji@825 248 DETACH DATABASE td;
yuuji@825 249 EOF
yuuji@825 250 while IFS='|' read rowid hgname; do
yuuji@825 251 # echo rowid=$rowid - `echo "$hgname"|unhexize|htmlescape`
yuuji@825 252 htmlgn=`echo $hgname|unhexize|htmlescape`
yuuji@825 253 printf '<a href="%s?grp+%d">%s</a> ' "$cgi" "$rowid" "$htmlgn"
yuuji@825 254 done | {
yuuji@825 255 read ans
yuuji@825 256 if [ -n "$ans" ]; then
yuuji@825 257 w=`echo $wname|htmlescape`
yuuji@826 258 u="<a href=\"$cgi?grps\"><span class=\"pre\">$w</span></a>"
yuuji@825 259 cat<<-EOF
yuuji@828 260 GUIDE:<h2>`echo "$guide"|htmlescape`</h2>
yuuji@825 261 <tr>
yuuji@826 262 <tr><td>$u $s</td>
yuuji@825 263 <td>$ans</td>
yuuji@825 264 </dl>
yuuji@825 265 EOF
yuuji@825 266 fi
yuuji@825 267 }
yuuji@828 268 }
yuuji@825 269
yuuji@825 270 peekgrpworlds() (
yuuji@828 271 # $1=(Pattern|mem:User)
yuuji@828 272 # err "pgw-1=[$1]"
yuuji@825 273 for wd in `worldnameDBlist`; do
yuuji@825 274 world=${wd%%:*}; wd=${wd#*:}
yuuji@825 275 worldname=${wd%:*}
yuuji@825 276 d=${wd#*:}
yuuji@825 277 if [ ! $db -ef $d -a -s $d ]; then
yuuji@827 278 grepgrpworld "$world" "$worldname" "$1" "$d"
yuuji@825 279 fi
yuuji@825 280 done | {
yuuji@825 281 result=`cat`
yuuji@825 282 if [ -n "$result" ]; then
yuuji@828 283 cat<<-EOF
yuuji@828 284 `echo "$result"|sed 's/^GUIDE://;2q'`
yuuji@828 285 <table class="b">
yuuji@828 286 `echo "$result"|grep -v '^GUIDE:'`
yuuji@828 287 </table>
yuuji@828 288 EOF
yuuji@825 289 fi
yuuji@825 290 }
yuuji@825 291 )