OSDN Git Service

[BUG FIX] Evaluation of old origins was incomplete for merged ports.
[portsreinstall/current.git] / lib / libdatabase_query.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # - Operations for queries to the temporary database -
5 # Copyright (C) 2013-2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
8
9 # ============= Show a list of failed ports with their reasons =============
10 database_query_show_list_failure ()
11 {
12         local tmp_valid
13         tmp_valid=${TMPDIR}/database_query_show_list_failure:valid
14         if [ `cat "${DBDIR}/failed.list" 2> /dev/null | wc -l` -eq 0 ]
15         then
16                 message_echo "INFO: No item is registered in this list."
17                 return 1
18         fi
19         grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern" "${DBDIR}/failed.list" 2> /dev/null \
20                 | while read origin
21         do
22                 grep -q -Fx "$origin" "${DBDIR}/stage.loop_list/ports_to_delete" 2> /dev/null \
23                         || echo "$origin"
24         done > $tmp_valid
25         if [ `cat "$tmp_valid" 2> /dev/null | wc -l` -eq 0 ]
26         then
27                 message_echo "INFO: No valid item is registered in this list."
28                 return 1
29         fi
30         while read origin
31         do
32                 note=`cat "${DBDIR}/notes/$origin/note_failtre" 2> /dev/null || :`
33                 resolved=no
34                 grep -q -Fx "$origin" "${DBDIR}/manually_done.list" 2> /dev/null && resolved=yes
35                 pkgtag=`cat "${DBDIR}/moved_from/$origin/pkgtag" 2> /dev/null || :`
36                 if [ $opt_batch_mode = no ]
37                 then
38                         case $resolved in
39                         no )    resolved=;;
40                         yes )   resolved=', resolved';;
41                         esac
42                         if [ -n "$note" ]
43                         then
44                                 detail="while [$note]"
45                         else
46                                 detail="by unrecorded reasons"
47                         fi
48                         if [ -n "$pkgtag" ]
49                         then
50                                 echo "$origin ($pkgtag) (error $detail$resolved)"
51                         else
52                                 echo "$origin (error $detail$resolved)"
53                         fi
54                 else
55                         printf "%s\t%s\t%s\t%s\n" "$origin" "$pkgtag" "$note" "$resolved"
56                 fi
57         done < $tmp_valid
58         :
59 }
60
61 # ============= Show a list of failed restoration of conflict =============
62 database_query_show_list_failed_conflicts_restoration ()
63 {
64         if [ `cat "${DBDIR}/deleted_conflicts" 2> /dev/null | wc -l` -eq 0 ]
65         then
66                 message_echo "INFO: No item is registered in this list."
67                 return 1
68         fi
69         grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" \
70                 | while read origin pkg
71                 do
72                         pkg_regexp=`str_escape_regexp "$pkg"`
73                         against=`grep -E "^$pkg_regexp:" "${DBDIR}/forbidden_conflicts" 2> /dev/null | cut -d : -f 2,3 | sort -u`
74                         if [ $opt_batch_mode = no ]
75                         then
76                                 if [ -n "$pkg" ]
77                                 then
78                                         echo -n "$origin ($pkg)"
79                                 else
80                                         echo -n "$origin"
81                                 fi
82                                 if [ -n "$against" ]
83                                 then
84                                         echo -n " against "
85                                         against=`echo "$against" | sed 's/:/(/;s/$/)/' | tr '\n' ' '`
86                                         str_linearize_list_and "$against"
87                                 else
88                                         echo
89                                 fi
90                         else
91                                 against=`echo "$against" | tr '\n' '|' | sed 's/,$//'`
92                                 printf '%s\t%s\t%s\n' "$origin" "$pkg" "$against"
93                         fi
94                 done
95         :
96 }
97
98 # ============= Insert initial flavored origins to a list of flavored origins =============
99 database_query_add_initial_origins ()
100 {
101         local origin
102         while read origin
103         do
104                 echo "$origin"
105                 [ -e "${DBDIR}/moved_from/$origin/initial_orig" ] || continue
106                 cat "${DBDIR}/moved_from/$origin/initial_orig"
107         done
108         :
109 }
110
111 # ============= Get target attributes =============
112 database_query_get_target_attributes ()
113 {
114         local prefix origin _is_all _is_target _is_requires_requirements _is_initial_requirements _is_requires_dependents _is_initial_dependents _is_requires_requirements_complement _is_relevant infofile tag level
115         prefix=$1
116         origin=$2
117         _is_all=y
118         _is_target=
119         _is_requires_requirements=
120         _is_initial_requirements=
121         _is_requires_dependents=
122         _is_initial_dependents=
123         _is_requires_requirements_complement=
124         _is_relevant=y
125         if [ ! -e "${DBDIR}/target_all" -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
126         then
127                 _is_all=
128                 tag=`options_get_dependency_type`
129                 level=full
130                 [ $opt_only_target_scope = yes ] && level=direct
131                 infofile=${DBDIR}/targets/$origin/attrs.${tag}.${level}
132                 if [ -e "$infofile" ]
133                 then
134                         . "$infofile"
135                 else
136                         _is_relevant=
137                 fi
138         fi
139         eval ${prefix}_is_all=\$\{_is_all\}
140         eval ${prefix}_is_target=\$\{_is_target\}
141         eval ${prefix}_is_requires_requirements=\$\{_is_requires_requirements\}
142         eval ${prefix}_is_initial_requirements=\$\{_is_initial_requirements\}
143         eval ${prefix}_is_requires_dependents=\$\{_is_requires_dependents\}
144         eval ${prefix}_is_initial_dependents=\$\{_is_initial_dependents\}
145         eval ${prefix}_is_requires_requirements_complement=\$\{_is_requires_requirements_complement\}
146         eval ${prefix}_is_relevant=\$\{_is_relevant\}
147 }
148
149 # ============= Check whether (re/de)installation of a port is suppressed =============
150 database_query_is_a_port_suppressed ()
151 {
152         local origin flags flag
153         origin=$1
154         flags=
155         [ $opt_suppress_self_upadte = yes ] && flags=SUPPRESSED_SELF
156         [ $opt_suppress_pkgtools_upadte = yes ] && flags="$flags SUPPRESSED_PKGNG"
157         for flag in $flags
158         do
159                 for db in initial moved_from
160                 do
161                         [ -e "${DBDIR}/$db/$origin/$flag" ] && return
162                 done
163         done
164         return 1
165 }
166
167 # ============= Check whether a port needs to be updated or upgraded =============
168 database_query_does_a_port_need_update ()
169 {
170         local origin dbpath frompath new_version current_version
171         origin=$1
172         dbpath=${DBDIR}/requires/$origin
173         frompath=${DBDIR}/moved_from/$origin
174         [ -e "$dbpath/conf_updated" ] && return
175         [ -e "$dbpath/new_version" ] || return
176         new_version=`cat "$dbpath/new_version"`
177         current_version=`cat "$frompath/current_version"`
178         [ "x$current_version" != "x$new_version" ]
179 }
180
181 # ============= Check before operations of a command which need the temporary database completely prepared =============
182 database_query_chk_preparation_completion ()
183 {
184         program_chk_stage_complete PREPARATION && return
185         message_echo "ERROR: Database has to be built completely before executing this command." >&2
186         exit 1
187 }
188
189 # ============= Get a make variable value of a port =============
190 database_query_get_makevar_val ()
191 {
192         local origin variable dbdir cache value
193         origin=$1
194         variable=$2
195         dbdir=${DBDIR}/requires/$origin
196         cache=$dbdir/makevar/$variable
197         if [ -e "$cache" ]
198         then
199                 cat "$cache"
200         else
201                 value=`database_build_make "$origin" -V "$variable"`
202                 if [ -d "$dbdir" ] && misc_is_superuser_privilege
203                 then
204                         [ -d "$dbdir/makevar" ] || mkdir "$dbdir/makevar"
205                         echo "$value" > $cache.tmp
206                         mv "$cache.tmp" "$cache"
207                 fi
208                 echo "$value"
209         fi
210 }
211
212 # ============= Check whether configurations for a port is default =============
213 database_query_is_default_conf ()
214 {
215         local origin mode dbpath tmp_msg is_customized is_requiremnt_replaced files tmp_old tmp_new origin_requirement tmp_msg_customized
216         origin=$1
217         mode=$2
218         dbpath=${DBDIR}/requires/$origin
219         if [ ! -e "$dbpath/is_customized" ]
220         then
221                 tmp_msg=${TMPDIR}/database_query_is_default_conf:msg
222                 cp /dev/null "$tmp_msg"
223                 is_customized=no
224                 if [ `ls "${DBDIR}/conf/each_port/$origin" 2> /dev/null | wc -l` -gt 0 ]
225                 then
226                         files=`ls "${DBDIR}/conf/each_port/$origin" | sed -E 's/^([^.]+).*/\1/' | str_concat_items_for_sentence`
227                         echo "Knobs and miscellaneous customization by $files," >> $tmp_msg
228                         is_customized=yes
229                 fi
230                 if ! diff -q "$dbpath/ports_options.default" "$dbpath/ports_options.current" > /dev/null 2>&1
231                 then
232                         echo "Non-default port options," >> $tmp_msg
233                         is_customized=yes
234                 fi
235                 if grep -q -Fx "$origin" "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null
236                 then
237                         echo "Explicit specification as non-default in ${APPNAME}.conf," >> $tmp_msg
238                         is_customized=yes
239                 fi
240                 tmp_old=${TMPDIR}/database_query_is_default_conf:old
241                 tmp_new=${TMPDIR}/database_query_is_default_conf:new
242                 is_requiremnt_replaced=no
243                 if fileedit_manipulate_old_new_lines "$dbpath/requirements.all.direct.orig" "$dbpath/requirements.all.direct" \
244                         "$tmp_old" "$tmp_new"
245                 then
246                         echo "Replacement in requirements:" >> $tmp_msg
247                         echo "-------- FROM --------" >> $tmp_msg
248                         sed 's/^/ /' "$tmp_old" >> $tmp_msg
249                         echo "--------  TO  --------" >> $tmp_msg
250                         sed 's/^/ /' "$tmp_new" >> $tmp_msg
251                         echo "----------------------" >> $tmp_msg
252                         is_customized=yes
253                 fi
254                 for origin_requirement in `cat "$dbpath/requirements.all.direct" 2> /dev/null`
255                 do
256                         database_query_is_default_conf "$origin_requirement" quiet && continue
257                         echo "Non-default requirement $origin_requirement," >> $tmp_msg
258                         is_customized=yes
259                 done
260                 { [ $is_customized = yes ] && cat "$tmp_msg"; } > $dbpath/is_customized.tmp
261                 mv "$dbpath/is_customized.tmp" "$dbpath/is_customized"
262         fi
263         [ `wc -c < $dbpath/is_customized` -eq 0 ] && return
264         if [ "x$mode" != xquiet ]
265         then
266                 tmp_msg_customized=${TMPDIR}/database_query_is_default_conf:msg_customized
267                 message_echo "INFO: This port is configured to be non-default because of"
268                 sed 's/^/         /' "$dbpath/is_customized" > $tmp_msg_customized
269                 message_cat "$tmp_msg_customized"
270                 message_echo "      so the prebuilt package is not used."
271         fi
272         return 1
273 }
274
275 # ============= Output of lists in which each matching port is registered =============
276 database_query_show_list_inclusion_of_matching_port ()
277 {
278         local grandtitle lists pkgnamedb deptag level isfirst origin_target pkg_target table_target
279         grandtitle=$1
280         lists=$2
281         pkgnamedb=$3
282         deptag=$4
283         level=$5
284         shift 5
285         message_echo "[$grandtitle]"
286         message_dependency_scope
287         message_echo
288         isfirst=y
289         for origin_target in `pkgsys_eval_ports_glob "$@"`
290         do
291                 pkg_target=
292                 for table_target in $pkgnamedb
293                 do
294                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
295                         [ -n "$pkg_target" ] && break
296                 done
297                 [ -n "$pkg_target" ] || continue
298                 isfirst=n
299                 match=
300                 for subject in `echo "$lists" | tr \| ' '`
301                 do
302                         database_query_exists_in_list "$origin_target" "$subject" "$deptag" "$level" \
303                                 && match="$match $subject"
304                 done
305                 if [ $opt_batch_mode = no ]
306                 then
307                         echo -n "$origin_target ($pkg_target): "
308                         echo "$match" | sed 's/^ *//;s/ /, /g'
309                 else
310                         printf '%s\t%s\t' "$origin_target" "$pkg_target"
311                         echo "$match" | sed 's/^ *//;s/ /,/g'
312                 fi
313         done
314         if [ "$isfirst" = y ]
315         then
316                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
317                 exit 1
318         fi
319         :
320 }
321
322 # ============= Output of "show" command for port lists =============
323 database_query_show_port_lists ()
324 {
325         local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
326         grandtitle=$1
327         title=$2
328         list=$3
329         listdb=$4
330         pkgnamedb=$5
331         shift 5
332         message_echo "[$grandtitle]"
333         message_dependency_scope
334         message_echo
335         isfirst=y
336         for origin_target in `pkgsys_eval_ports_glob "$@"`
337         do
338                 pkg_target=
339                 for table_target in $pkgnamedb
340                 do
341                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
342                         [ -n "$pkg_target" ] && break
343                 done
344                 [ -n "$pkg_target" ] || continue
345                 [ "$isfirst" = y ] || message_echo
346                 isfirst=n
347                 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
348                 list_target=
349                 for table_target in $listdb
350                 do
351                         list_target=${DBDIR}/$table_target/$origin_target/$list
352                         [ -e "$list_target" ] && break
353                 done
354                 [ -e "$list_target" ] || continue
355                 if [ $opt_batch_mode = no ]
356                 then
357                         while read origin
358                         do
359                                 pkg=
360                                 for table in $pkgnamedb
361                                 do
362                                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
363                                         [ -n "$pkg" ] && break
364                                 done
365                                 [ -n "$pkg" ] || continue
366                                 echo "$origin ($pkg)"
367                         done < $list_target
368                 else
369                         while read origin
370                         do
371                                 pkg=
372                                 for table in $pkgnamedb
373                                 do
374                                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
375                                         [ -n "$pkg" ] && break
376                                 done
377                                 [ -n "$pkg" ] || continue
378                                 printf '%s\t%s\t%s\t%s\n' "$origin_target" "$pkg_target" "$origin" "$pkg"
379                         done < $list_target
380                 fi
381         done
382         if [ "$isfirst" = y ]
383         then
384                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
385                 exit 1
386         fi
387         :
388 }
389
390 # ============= Output of "show" command for two column lists =============
391 database_query_show_two_column_lists ()
392 {
393         local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
394         grandtitle=$1
395         title=$2
396         list=$3
397         listdb=$4
398         pkgnamedb=$5
399         shift 5
400         message_echo "[$grandtitle]"
401         message_echo
402         isfirst=y
403         for origin_target in `pkgsys_eval_ports_glob "$@"`
404         do
405                 pkg_target=
406                 for table_target in $pkgnamedb
407                 do
408                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
409                         [ -n "$pkg_target" ] && break
410                 done
411                 [ -n "$pkg_target" ] || continue
412                 [ "$isfirst" = y ] || message_echo
413                 isfirst=n
414                 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
415                 list_target=
416                 for table_target in $listdb
417                 do
418                         list_target=${DBDIR}/$table_target/$origin_target/$list
419                         [ -e "$list_target" ] && break
420                 done
421                 [ -e "$list_target" ] || continue
422                 if [ $opt_batch_mode = no ]
423                 then
424                         sed 's/[[:space:]]/: /' < $list_target
425                 else
426                         cat  < $list_target
427                 fi
428         done
429         if [ "$isfirst" = y ]
430         then
431                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
432                 exit 1
433         fi
434         :
435 }
436
437 # ============= Output of "show" command for a single list =============
438 database_query_show_single_list ()
439 {
440         local list pkgnamedb flag_filter_skip_unchanged flag_filter_only_target tmpflag_exists put_blankline
441         list=$1
442         pkgnamedb=$2
443         flag_filter_skip_unchanged=$3
444         flag_filter_only_target=$4
445         tmpflag_exists=${TMPDIR}/database_query_show_single_list::exists_item
446         if [ `cat "${DBDIR}/$list" 2> /dev/null | wc -l` -eq 0 ]
447         then
448                 message_echo "INFO: No item is registered in this list."
449                 return 1
450         fi
451         if ! program_chk_stage_complete PREPARATION
452         then
453                 message_echo "WARNING: The temporary database is incomplete. The raw list is shown." >&2
454                 cat "${DBDIR}/$list"
455                 return
456         fi
457         rm -f "$tmpflag_exists"
458         put_blankline=
459         if [ -n "$flag_filter_only_target" \
460                 -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
461         then
462                 message_echo "WARNING: Ports outside of the target scope are excluded." >&2
463                 put_blankline=y
464         fi
465         if [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes ]
466         then
467                 message_echo "WARNING: Ports which have been the newest with their all requirements from the first are excluded." >&2
468                 put_blankline=y
469         fi
470         [ -n "$put_blankline" ] && message_echo
471         while read origin
472         do
473                 [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes \
474                         -a ! -e "${DBDIR}/requires/$origin/$flag_filter_skip_unchanged" ] \
475                         && continue
476                 if [ -n "$flag_filter_only_target" ]
477                 then
478                         database_query_get_target_attributes currentorigin "$origin"
479                         [ -n "${currentorigin_is_relevant}" ] || continue
480                         database_query_is_a_port_suppressed "$origin" && continue
481                 fi
482                 pkg=
483                 for table in $pkgnamedb
484                 do
485                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
486                         [ -n "$pkg" ] && break
487                 done
488                 [ -n "$pkg" ] || continue
489                 touch "$tmpflag_exists"
490                 if [ $opt_batch_mode = no ]
491                 then
492                         echo "$origin ($pkg)"
493                 else
494                         printf '%s\t%s\n' "$origin" "$pkg"
495                 fi
496         done < ${DBDIR}/$list
497         [ -e "$tmpflag_exists" ] && return
498         message_echo "INFO: No item is registered in this list."
499         return 1
500 }
501
502 # ============= Check whether the upgrade is necessary for a port =============
503 database_query_is_necessary_upgrade ()
504 {
505         local origin nodedir dbsuffix tmpfile_new tmpfile_old tmpfile_diff
506         origin=$1
507         nodedir=${DBDIR}/requires/$origin
508         [ -e "$nodedir/installed_by_pkg" ] && return 1
509         dbsuffix=`options_get_dependency_type`.`options_get_dependency_level`
510         tmpfile_new=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.new
511         tmpfile_old=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.old
512         tmpfile_diff=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.diff
513         [ -e "$nodedir/failed_requirements.${dbsuffix}.previous" ] || return
514         sort -u "$nodedir/failed_requirements.${dbsuffix}" > $tmpfile_new 2> /dev/null || :
515         sort -u "$nodedir/failed_requirements.${dbsuffix}.previous" > $tmpfile_old 2> /dev/null || :
516         fileedit_exists_old_lines "$tmpfile_old" "$tmpfile_new"
517 }
518
519 # ============= Actual operations of "show" command for a single list =============
520 database_query_show_single_list_exec ()
521 {
522         local subject deptag level dbsuffix flag_filter_skip_unchanged flag_filter_only_target pkgnamedb
523         subject=$1
524         deptag=$2
525         level=$3
526         dbsuffix=$deptag.$level
527         flag_filter_skip_unchanged=
528         flag_filter_only_target=
529         pkgnamedb='requires obsolete initial'
530         case $subject in
531         todo )
532                 message_echo "The following ports remain in the (re)installation queue for the current do/redo process:"
533                 message_echo "It is noted that ports to be skipped can be included here."
534                 message_dependency_scope
535                 message_echo
536                 list=stage.loop_list/reinst_todo.remain
537                 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
538                 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
539                 flag_filter_only_target=y
540                 ;;
541         done )
542                 message_echo "The following ports have been successfully (re)installed or newly installed:"
543                 message_dependency_scope
544                 message_echo
545                 list=success.$dbsuffix.list
546                 flag_filter_skip_unchanged=necessary_upgrade_completed.$dbsuffix
547                 flag_filter_only_target=y
548                 ;;
549         redo )
550                 message_echo "The following ports need (re)installation but are to be skipped until any of their failed requirements succeeds:"
551                 message_dependency_scope
552                 message_echo
553                 list=todo_after_requirements_succeed.$dbsuffix.list
554                 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
555                 flag_filter_only_target=y
556                 ;;
557         resolved )
558                 message_echo "The following ports had problems which have been manually resolved:"
559                 message_echo
560                 list=manually_done.list
561                 ;;
562         failure )
563                 message_echo "The following ports experienced failures and kept to be old or uninstalled:"
564                 message_echo
565                 database_query_show_list_failure
566                 return
567                 ;;
568         conflict )
569                 message_echo "The following ports are temporarily deleted due to conflict:"
570                 message_echo
571                 database_query_show_list_failed_conflicts_restoration
572                 return
573                 ;;
574         taboo )
575                 message_echo "The following ports are registered as taboo:"
576                 message_echo
577                 list=taboo.all.list
578                 ;;
579         freeze )
580                 message_echo "The following ports are registered to freeze:"
581                 message_echo
582                 list=freeze.all.list
583                 ;;
584         need )
585                 message_echo "The following ports are registered as necessary:"
586                 message_echo
587                 list=need.list
588                 ;;
589         noneed )
590                 message_echo "The following ports are registered as unnecessary:"
591                 message_echo
592                 list=noneed.list
593                 ;;
594         restored )
595                 message_echo "The following leaf, obsolete or unneeded ports had been once deleted but are to be or have been restored:"
596                 message_echo
597                 list=stage.loop_list/ports_to_restore
598                 pkgnamedb='obsolete initial'
599                 flag_filter_only_target=y
600                 ;;
601         deleted )
602                 message_echo "The following leaf, obsolete or unneeded ports are to be or have been deleted:"
603                 message_echo
604                 list=stage.loop_list/ports_to_delete
605                 pkgnamedb='obsolete initial'
606                 flag_filter_only_target=y
607                 ;;
608         esac
609         database_query_show_single_list "$list" "$pkgnamedb" \
610                 "$flag_filter_skip_unchanged" "$flag_filter_only_target"
611 }
612
613 # ============= Check whether a port is registered in a list =============
614 database_query_exists_in_list ()
615 {
616         local origin subject deptag level tmp_list dbsuffix origin_esc
617         origin=$1
618         subject=$2
619         deptag=$3
620         level=$4
621         tmp_list=${TMPDIR}/database_query_exists_in_list:list
622         dbsuffix=$deptag.$level
623         origin_esc=`str_escape_regexp "$origin"`
624         case $subject in
625         todo )
626                 list=stage.loop_list/reinst_todo.remain
627                 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
628                 ;;
629         done )
630                 list=success.$dbsuffix.list
631                 ;;
632         redo )
633                 list=todo_after_requirements_succeed.$dbsuffix.list
634                 ;;
635         resolved )
636                 list=manually_done.list
637                 ;;
638         failure )
639                 list=failed.list
640                 ;;
641         conflict )
642                 grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" 2> /dev/null \
643                         | grep -q -E "^${origin_esc}[[:space:]]"
644                 return
645                 ;;
646         taboo )
647                 list=taboo.all.list
648                 ;;
649         freeze )
650                 list=freeze.all.list
651                 ;;
652         need )
653                 list=need.list
654                 ;;
655         noneed )
656                 list=noneed.list
657                 ;;
658         restored )
659                 list=stage.loop_list/ports_to_restore
660                 ;;
661         deleted )
662                 list=stage.loop_list/ports_to_delete
663                 ;;
664         esac
665         grep -q -Fx "$origin" "${DBDIR}/$list" 2> /dev/null
666 }
667
668 # ============= Check whether the requirements of installed packages match the port configuration =============
669 database_query_dependency_matching ()
670 {
671         local origin pkg tmp_inst tmp_db
672         origin=$1
673         [ -d "${DBDIR}/requires/$origin" ] || return
674         tmp_inst=${TMPDIR}/database_query_dependency_matching.installed
675         tmp_db=${TMPDIR}/database_query_dependency_matching.configured
676         pkg=`database_build_get_new_pkgname "$origin"`
677         [ -n "$pkg" ] || return
678         pkg_info_e "$pkg" || return
679         pkg_info_qr "$pkg" | grep -v '^[[:space:]]*$' | sort -u > $tmp_inst
680         database_build_get_full_run_requirement_pkgs "$origin" > $tmp_db
681         diff "$tmp_inst" "$tmp_db" > /dev/null 2>/dev/null
682 }
683
684 # ============= Check whether any of the requirements are locked because being missing ports to freeze =============
685 database_query_are_requirements_not_locked ()
686 {
687         local origin
688         origin=$1
689         cat "${DBDIR}/requires/$origin/requirements.all.direct" 2> /dev/null | while read origin_requirement
690         do
691                 pkg_requirement=`pkgsys_get_installed_pkg_from_origin "$origin_requirement"` || :
692                 if grep -q -Fx "$origin_requirement" "${DBDIR}/freeze.all.list" 2> /dev/null
693                 then
694                         [ -n "$pkg_requirement" ] || return
695                 elif [ -z "$pkg_requirement" ]
696                 then
697                         database_query_are_requirements_not_locked "$origin_requirement" || return
698                 fi
699         done
700         :
701 }
702
703 # ============= Check whether any of progress is made in the current run =============
704 database_query_is_any_progress ()
705 {
706         [ `cat "${DBDIR}/new_success_in_current_run" 2> /dev/null | wc -l` -gt 0 ]
707 }
708
709 # ============= Get the all initial origins, separated by line feed =============
710 database_query_initial_orgins ()
711 {
712         local origin origin_init
713         origin=$1
714         if [ -e "${DBDIR}/moved_from/$origin/old_origs" ]
715         then
716                 for origin_init in `cat "${DBDIR}/moved_from/$origin/old_origs"`
717                 do
718                         [ -e "${DBDIR}/initial/$origin_init/installed_version" ] && echo "$origin_init"
719                 done
720         else
721                 [ -e "${DBDIR}/initial/$origin/installed_version" ] && echo "$origin"
722         fi
723         :
724 }