OSDN Git Service

The options passed to portsreinstall in the builder chroot environment by portsreinst...
[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 # ============= Show installed ports which have been neither upgraded or reinstalled from the initial state =============
99 database_query_show_list_heritage ()
100 {
101         local srclist origin pkg
102         srclist=`ls "${DBDIR}"fossil_pkgs/heritage_since_* | head -n 1`
103         [ -e "$srclist" ] || return 0
104         while read origin
105         do
106                 pkg=`pkgsys_get_init_pkg_from_orig "$origin"`
107                 pkg_info_e "$pkg" || continue
108                 printf '%s\t%s' "$origin" "$pkg"
109         done < $srclist
110 }
111
112 # ============= Insert initial flavored origins to a list of flavored origins =============
113 database_query_add_initial_origins ()
114 {
115         local origin
116         while read origin
117         do
118                 echo "$origin"
119                 [ -e "${DBDIR}/moved_from/$origin/initial_orig" ] || continue
120                 cat "${DBDIR}/moved_from/$origin/initial_orig"
121         done
122         :
123 }
124
125 # ============= Get target attributes =============
126 database_query_get_target_attributes ()
127 {
128         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
129         prefix=$1
130         origin=$2
131         _is_all=y
132         _is_target=
133         _is_requires_requirements=
134         _is_initial_requirements=
135         _is_requires_dependents=
136         _is_initial_dependents=
137         _is_requires_requirements_complement=
138         _is_relevant=y
139         if [ ! -e "${DBDIR}/target_all" -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
140         then
141                 _is_all=
142                 tag=`options_get_dependency_type`
143                 level=full
144                 [ $opt_only_target_scope = yes ] && level=direct
145                 infofile=${DBDIR}/targets/$origin/attrs.${tag}.${level}
146                 if [ -e "$infofile" ]
147                 then
148                         . "$infofile"
149                 else
150                         _is_relevant=
151                 fi
152         fi
153         eval ${prefix}_is_all=\$\{_is_all\}
154         eval ${prefix}_is_target=\$\{_is_target\}
155         eval ${prefix}_is_requires_requirements=\$\{_is_requires_requirements\}
156         eval ${prefix}_is_initial_requirements=\$\{_is_initial_requirements\}
157         eval ${prefix}_is_requires_dependents=\$\{_is_requires_dependents\}
158         eval ${prefix}_is_initial_dependents=\$\{_is_initial_dependents\}
159         eval ${prefix}_is_requires_requirements_complement=\$\{_is_requires_requirements_complement\}
160         eval ${prefix}_is_relevant=\$\{_is_relevant\}
161 }
162
163 # ============= Check whether (re/de)installation of a port is suppressed =============
164 database_query_is_a_port_suppressed ()
165 {
166         local origin flags flag
167         origin=$1
168         flags=
169         [ $opt_suppress_self_upadte = yes ] && flags=SUPPRESSED_SELF
170         [ $opt_suppress_pkgtools_upadte = yes ] && flags="$flags SUPPRESSED_PKGNG"
171         for flag in $flags
172         do
173                 for db in initial moved_from
174                 do
175                         [ -e "${DBDIR}/$db/$origin/$flag" ] && return
176                 done
177         done
178         return 1
179 }
180
181 # ============= Check whether a port needs to be updated or upgraded =============
182 database_query_does_a_port_need_update ()
183 {
184         local origin dbpath frompath new_version current_version
185         origin=$1
186         dbpath=${DBDIR}/requires/$origin
187         frompath=${DBDIR}/moved_from/$origin
188         [ -e "$dbpath/conf_updated" ] && return
189         [ -e "$dbpath/new_version" ] || return
190         new_version=`cat "$dbpath/new_version"`
191         current_version=`cat "$frompath/current_version"`
192         [ "x$current_version" != "x$new_version" ]
193 }
194
195 # ============= Check before operations of a command which need the temporary database completely prepared =============
196 database_query_chk_preparation_completion ()
197 {
198         program_chk_stage_complete PREPARATION && return
199         message_echo "ERROR: Database has to be built completely before executing this command." >&2
200         exit 1
201 }
202
203 # ============= Get a make variable value of a port =============
204 database_query_get_makevar_val ()
205 {
206         local origin variable dbdir cache value
207         origin=$1
208         variable=$2
209         dbdir=${DBDIR}/requires/$origin
210         cache=$dbdir/makevar/$variable
211         if [ -e "$cache" ]
212         then
213                 cat "$cache"
214         else
215                 value=`database_build_make "$origin" -V "$variable"`
216                 if [ -d "$dbdir" ] && misc_is_superuser_privilege
217                 then
218                         [ -d "$dbdir/makevar" ] || mkdir "$dbdir/makevar"
219                         echo "$value" > $cache.tmp
220                         mv "$cache.tmp" "$cache"
221                 fi
222                 echo "$value"
223         fi
224 }
225
226 # ============= Get a configured value of a port =============
227 database_query_get_config_val ()
228 {
229         local origin variable dbdir cache value
230         origin=$1
231         variable=$2
232         dbfile=${DBDIR}/conf/each_port/$origin/$variable.conf
233         cat "$dbfile" 2> /dev/null || :
234 }
235
236 # ============= Check whether configurations for a port is default =============
237 database_query_is_default_conf ()
238 {
239         local origin mode dbpath tmp_msg is_customized is_requiremnt_replaced files tmp_old tmp_new origin_requirement tmp_msg_customized
240         origin=$1
241         mode=$2
242         dbpath=${DBDIR}/requires/$origin
243         if [ ! -e "$dbpath/is_customized" ]
244         then
245                 tmp_msg=${TMPDIR}/database_query_is_default_conf:msg
246                 cp /dev/null "$tmp_msg"
247                 is_customized=no
248                 if [ `ls "${DBDIR}/conf/each_port/$origin" 2> /dev/null | wc -l` -gt 0 ]
249                 then
250                         files=`ls "${DBDIR}/conf/each_port/$origin" | sed -E 's/^([^.]+).*/\1/' | str_concat_items_for_sentence`
251                         echo "Knobs and miscellaneous customization by $files," >> $tmp_msg
252                         is_customized=yes
253                 fi
254                 if ! diff -q "$dbpath/ports_options.default" "$dbpath/ports_options.current" > /dev/null 2>&1
255                 then
256                         echo "Non-default port options," >> $tmp_msg
257                         is_customized=yes
258                 fi
259                 if grep -q -Fx "$origin" "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null
260                 then
261                         echo "Explicit specification as non-default in ${APPNAME}.conf," >> $tmp_msg
262                         is_customized=yes
263                 fi
264                 tmp_old=${TMPDIR}/database_query_is_default_conf:old
265                 tmp_new=${TMPDIR}/database_query_is_default_conf:new
266                 is_requiremnt_replaced=no
267                 if fileedit_manipulate_old_new_lines "$dbpath/requirements.all.direct.orig" "$dbpath/requirements.all.direct" \
268                         "$tmp_old" "$tmp_new"
269                 then
270                         echo "Replacement in requirements:" >> $tmp_msg
271                         echo "-------- FROM --------" >> $tmp_msg
272                         sed 's/^/ /' "$tmp_old" >> $tmp_msg
273                         echo "--------  TO  --------" >> $tmp_msg
274                         sed 's/^/ /' "$tmp_new" >> $tmp_msg
275                         echo "----------------------" >> $tmp_msg
276                         is_customized=yes
277                 fi
278                 for origin_requirement in `cat "$dbpath/requirements.all.direct" 2> /dev/null`
279                 do
280                         database_query_is_default_conf "$origin_requirement" quiet && continue
281                         echo "Non-default requirement $origin_requirement," >> $tmp_msg
282                         is_customized=yes
283                 done
284                 { [ $is_customized = yes ] && cat "$tmp_msg"; } > $dbpath/is_customized.tmp
285                 mv "$dbpath/is_customized.tmp" "$dbpath/is_customized"
286         fi
287         [ `wc -c < $dbpath/is_customized` -eq 0 ] && return
288         if [ "x$mode" != xquiet ]
289         then
290                 tmp_msg_customized=${TMPDIR}/database_query_is_default_conf:msg_customized
291                 message_echo "INFO: This port is configured to be non-default because of"
292                 sed 's/^/         /' "$dbpath/is_customized" > $tmp_msg_customized
293                 message_cat "$tmp_msg_customized"
294                 message_echo "      so the prebuilt package is not used."
295         fi
296         return 1
297 }
298
299 # ============= Output of lists in which each matching port is registered =============
300 database_query_show_list_inclusion_of_matching_port ()
301 {
302         local grandtitle lists pkgnamedb deptag level isfirst origin_target pkg_target table_target
303         grandtitle=$1
304         lists=$2
305         pkgnamedb=$3
306         deptag=$4
307         level=$5
308         shift 5
309         message_echo "[$grandtitle]"
310         message_dependency_scope "$deptag" "$level"
311         message_echo
312         isfirst=y
313         for origin_target in `pkgsys_eval_ports_glob "$@"`
314         do
315                 pkg_target=
316                 for table_target in $pkgnamedb
317                 do
318                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
319                         [ -n "$pkg_target" ] && break
320                 done
321                 [ -n "$pkg_target" ] || continue
322                 isfirst=n
323                 match=
324                 for subject in `echo "$lists" | tr \| ' '`
325                 do
326                         database_query_exists_in_list "$origin_target" "$subject" "$deptag" "$level" \
327                                 && match="$match $subject"
328                 done
329                 if [ $opt_batch_mode = no ]
330                 then
331                         echo -n "$origin_target ($pkg_target): "
332                         echo "$match" | sed 's/^ *//;s/ /, /g'
333                 else
334                         printf '%s\t%s\t' "$origin_target" "$pkg_target"
335                         echo "$match" | sed 's/^ *//;s/ /,/g'
336                 fi
337         done
338         if [ "$isfirst" = y ]
339         then
340                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
341                 exit 1
342         fi
343         :
344 }
345
346 # ============= Output of "show" command for port lists =============
347 database_query_show_port_lists ()
348 {
349         local grandtitle title list listdb pkgnamedb deptag level isfirst origin_target pkg_target table_target list_target
350         grandtitle=$1
351         title=$2
352         list=$3
353         listdb=$4
354         pkgnamedb=$5
355         deptag=$6
356         level=$7
357         shift 7
358         message_echo "[$grandtitle]"
359         message_dependency_scope "$deptag" "$level"
360         message_echo
361         isfirst=y
362         for origin_target in `pkgsys_eval_ports_glob "$@"`
363         do
364                 pkg_target=
365                 for table_target in $pkgnamedb
366                 do
367                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
368                         [ -n "$pkg_target" ] && break
369                 done
370                 [ -n "$pkg_target" ] || continue
371                 [ "$isfirst" = y ] || message_echo
372                 isfirst=n
373                 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
374                 list_target=
375                 for table_target in $listdb
376                 do
377                         list_target=${DBDIR}/$table_target/$origin_target/$list
378                         [ -e "$list_target" ] && break
379                 done
380                 [ -e "$list_target" ] || continue
381                 if [ $opt_batch_mode = no ]
382                 then
383                         while read origin
384                         do
385                                 pkg=
386                                 for table in $pkgnamedb
387                                 do
388                                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
389                                         [ -n "$pkg" ] && break
390                                 done
391                                 [ -n "$pkg" ] || continue
392                                 echo "$origin ($pkg)"
393                         done < $list_target
394                 else
395                         while read origin
396                         do
397                                 pkg=
398                                 for table in $pkgnamedb
399                                 do
400                                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
401                                         [ -n "$pkg" ] && break
402                                 done
403                                 [ -n "$pkg" ] || continue
404                                 printf '%s\t%s\t%s\t%s\n' "$origin_target" "$pkg_target" "$origin" "$pkg"
405                         done < $list_target
406                 fi
407         done
408         if [ "$isfirst" = y ]
409         then
410                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
411                 exit 1
412         fi
413         :
414 }
415
416 # ============= Output of "show" command for log files =============
417 database_query_show_log ()
418 {
419         local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
420         grandtitle=$1
421         title=$2
422         list=$3
423         listdb=$4
424         pkgnamedb=$5
425         shift 5
426         message_echo "[$grandtitle]"
427         message_echo
428         isfirst=y
429         for origin_target in `pkgsys_eval_ports_glob "$@"`
430         do
431                 pkg_target=
432                 for table_target in $pkgnamedb
433                 do
434                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
435                         [ -n "$pkg_target" ] && break
436                 done
437                 [ -n "$pkg_target" ] || continue
438                 [ "$isfirst" = y ] || message_echo
439                 isfirst=n
440                 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
441                 list_target=
442                 for table_target in $listdb
443                 do
444                         list_target=${DBDIR}/$table_target/$origin_target/$list
445                         [ -e "$list_target" ] && break
446                 done
447                 [ -e "$list_target" ] || continue
448                 cat  < $list_target
449                 echo
450         done
451         if [ "$isfirst" = y ]
452         then
453                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
454                 exit 1
455         fi
456         :
457 }
458
459 # ============= Output of "show" command for two column lists =============
460 database_query_show_two_column_lists ()
461 {
462         local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
463         grandtitle=$1
464         title=$2
465         list=$3
466         listdb=$4
467         pkgnamedb=$5
468         shift 5
469         message_echo "[$grandtitle]"
470         message_echo
471         isfirst=y
472         for origin_target in `pkgsys_eval_ports_glob "$@"`
473         do
474                 pkg_target=
475                 for table_target in $pkgnamedb
476                 do
477                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
478                         [ -n "$pkg_target" ] && break
479                 done
480                 [ -n "$pkg_target" ] || continue
481                 [ "$isfirst" = y ] || message_echo
482                 isfirst=n
483                 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
484                 list_target=
485                 for table_target in $listdb
486                 do
487                         list_target=${DBDIR}/$table_target/$origin_target/$list
488                         [ -e "$list_target" ] && break
489                 done
490                 [ -e "$list_target" ] || continue
491                 if [ $opt_batch_mode = no ]
492                 then
493                         sed 's/[[:space:]]/: /' < $list_target
494                 else
495                         cat  < $list_target
496                 fi
497         done
498         if [ "$isfirst" = y ]
499         then
500                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
501                 exit 1
502         fi
503         :
504 }
505
506 # ============= Output of "show" command for a single list =============
507 database_query_show_single_list ()
508 {
509         local list pkgnamedb flag_filter_skip_unchanged flag_filter_only_target tmpflag_exists put_blankline
510         list=$1
511         pkgnamedb=$2
512         flag_filter_skip_unchanged=$3
513         flag_filter_only_target=$4
514         tmpflag_exists=${TMPDIR}/database_query_show_single_list::exists_item
515         if [ `cat "${DBDIR}/$list" 2> /dev/null | wc -l` -eq 0 ]
516         then
517                 message_echo "INFO: No item is registered in this list."
518                 return 1
519         fi
520         if ! program_chk_stage_complete PREPARATION
521         then
522                 message_echo "WARNING: The temporary database is incomplete. The raw list is shown." >&2
523                 cat "${DBDIR}/$list"
524                 return
525         fi
526         rm -f "$tmpflag_exists"
527         put_blankline=
528         if [ -n "$flag_filter_only_target" \
529                 -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
530         then
531                 message_echo "WARNING: Ports outside of the target scope are excluded." >&2
532                 put_blankline=y
533         fi
534         if [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes ]
535         then
536                 message_echo "WARNING: Ports which have been the newest with their all requirements from the first are excluded." >&2
537                 put_blankline=y
538         fi
539         [ -n "$put_blankline" ] && message_echo
540         while read origin
541         do
542                 [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes \
543                         -a ! -e "${DBDIR}/requires/$origin/$flag_filter_skip_unchanged" ] \
544                         && continue
545                 if [ -n "$flag_filter_only_target" ]
546                 then
547                         database_query_get_target_attributes currentorigin "$origin"
548                         [ -n "${currentorigin_is_relevant}" ] || continue
549                         database_query_is_a_port_suppressed "$origin" && continue
550                 fi
551                 pkg=
552                 for table in $pkgnamedb
553                 do
554                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
555                         [ -n "$pkg" ] && break
556                 done
557                 [ -n "$pkg" ] || continue
558                 touch "$tmpflag_exists"
559                 if [ $opt_batch_mode = no ]
560                 then
561                         echo "$origin ($pkg)"
562                 else
563                         printf '%s\t%s\n' "$origin" "$pkg"
564                 fi
565         done < ${DBDIR}/$list
566         [ -e "$tmpflag_exists" ] && return
567         message_echo "INFO: No item is registered in this list."
568         return 1
569 }
570
571 # ============= Check whether the upgrade is necessary for a port =============
572 database_query_is_necessary_upgrade ()
573 {
574         local origin nodedir dbsuffix tmpfile_new tmpfile_old tmpfile_diff
575         origin=$1
576         nodedir=${DBDIR}/requires/$origin
577         [ -e "$nodedir/installed_by_pkg" ] && return 1
578         dbsuffix=`options_get_dependency_type`.`options_get_dependency_level`
579         tmpfile_new=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.new
580         tmpfile_old=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.old
581         tmpfile_diff=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.diff
582         [ -e "$nodedir/failed_requirements.${dbsuffix}.previous" ] || return
583         sort -u "$nodedir/failed_requirements.${dbsuffix}" > $tmpfile_new 2> /dev/null || :
584         sort -u "$nodedir/failed_requirements.${dbsuffix}.previous" > $tmpfile_old 2> /dev/null || :
585         fileedit_exists_old_lines "$tmpfile_old" "$tmpfile_new"
586 }
587
588 # ============= Actual operations of "show" command for a single list =============
589 database_query_show_single_list_exec ()
590 {
591         local subject deptag level dbsuffix flag_filter_skip_unchanged flag_filter_only_target pkgnamedb
592         subject=$1
593         deptag=$2
594         level=$3
595         dbsuffix=$deptag.$level
596         flag_filter_skip_unchanged=
597         flag_filter_only_target=
598         pkgnamedb='moved_from obsolete initial'
599         case $subject in
600         todo )
601                 message_echo "The following ports remain in the (re)installation queue for the current do/redo process:"
602                 message_echo "It is noted that ports to be skipped can be included here."
603                 message_dependency_scope "$deptag" "$level"
604                 message_echo
605                 list=stage.loop_list/reinst_todo.remain
606                 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
607                 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
608                 flag_filter_only_target=y
609                 ;;
610         done )
611                 message_echo "The following ports have been successfully (re)installed or newly installed:"
612                 message_dependency_scope "$deptag" "$level"
613                 message_echo
614                 list=success.$dbsuffix.list
615                 flag_filter_skip_unchanged=necessary_upgrade_completed.$dbsuffix
616                 flag_filter_only_target=y
617                 ;;
618         redo )
619                 message_echo "The following ports need (re)installation but are to be skipped until any of their failed requirements succeeds:"
620                 message_dependency_scope "$deptag" "$level"
621                 message_echo
622                 list=todo_after_requirements_succeed.$dbsuffix.list
623                 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
624                 flag_filter_only_target=y
625                 ;;
626         resolved )
627                 message_echo "The following ports had problems which have been manually resolved:"
628                 message_echo
629                 list=manually_done.list
630                 ;;
631         inst_by_pkg )
632                 message_echo "The following ports are configured default and installed by prebuilt packages"
633                 message_echo
634                 list=installation_complete_by_pkg.list
635                 ;;
636         failure )
637                 message_echo "The following ports experienced failures and kept to be old or uninstalled:"
638                 message_echo
639                 database_query_show_list_failure
640                 return
641                 ;;
642         heritage )
643                 message_echo "The following ports are neither upgraded or reinstalled from the initial state:"
644                 message_echo
645                 database_query_show_list_heritage
646                 return
647                 ;;
648         conflict )
649                 message_echo "The following ports are temporarily deleted due to conflict:"
650                 message_echo
651                 database_query_show_list_failed_conflicts_restoration
652                 return
653                 ;;
654         taboo )
655                 message_echo "The following ports are registered as taboo:"
656                 message_echo
657                 list=taboo.all.list
658                 ;;
659         freeze )
660                 message_echo "The following ports are registered to freeze:"
661                 message_echo
662                 list=freeze.all.list
663                 ;;
664         need )
665                 message_echo "The following ports are registered as necessary:"
666                 message_echo
667                 list=need.list
668                 ;;
669         noneed )
670                 message_echo "The following ports are registered as unnecessary:"
671                 message_echo
672                 list=noneed.list
673                 ;;
674         restored )
675                 message_echo "The following leaf, obsolete or unneeded ports had been once deleted but are to be or have been restored:"
676                 message_echo
677                 list=stage.loop_list/ports_to_restore
678                 pkgnamedb='moved_from obsolete initial'
679                 flag_filter_only_target=y
680                 ;;
681         deleted )
682                 message_echo "The following leaf, obsolete or unneeded ports are to be or have been deleted:"
683                 message_echo
684                 list=stage.loop_list/ports_to_delete
685                 pkgnamedb='moved_from obsolete initial'
686                 flag_filter_only_target=y
687                 ;;
688         leaves )
689                 if [ -z "$deptag" ]
690                 then
691                         message_echo "The following ports are all detected leaf ports:"
692                         list=leaf_ports
693                 else
694                         message_echo "The following ports are all $deptag leaf ports:"
695                         list=leaf_ports_to_delete.$deptag
696                 fi
697                 message_echo
698                 pkgnamedb='moved_from obsolete initial'
699                 flag_filter_only_target=y
700                 ;;
701         obsolete )
702                 if [ -z "$deptag" ]
703                 then
704                         message_echo "The following ports are all detected obsolete ports:"
705                         list=obsolete_ports.can_be_deleted
706                 else
707                         message_echo "The following ports are all $deptag obsolete ports:"
708                         list=obsolete_ports_to_delete.$deptag
709                 fi
710                 message_echo
711                 pkgnamedb='moved_from obsolete initial'
712                 flag_filter_only_target=y
713                 ;;
714         esac
715         database_query_show_single_list "$list" "$pkgnamedb" \
716                 "$flag_filter_skip_unchanged" "$flag_filter_only_target"
717 }
718
719 # ============= Check whether a port is registered in a list =============
720 database_query_exists_in_list ()
721 {
722         local origin subject deptag level tmp_list dbsuffix origin_esc
723         origin=$1
724         subject=$2
725         deptag=$3
726         level=$4
727         tmp_list=${TMPDIR}/database_query_exists_in_list:list
728         dbsuffix=$deptag.$level
729         origin_esc=`str_escape_regexp "$origin"`
730         case $subject in
731         todo )
732                 list=stage.loop_list/reinst_todo.remain
733                 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
734                 ;;
735         done )
736                 list=success.$dbsuffix.list
737                 ;;
738         redo )
739                 list=todo_after_requirements_succeed.$dbsuffix.list
740                 ;;
741         resolved )
742                 list=manually_done.list
743                 ;;
744         inst_by_pkg )
745                 list=installation_complete_by_pkg.list
746                 ;;
747         failure )
748                 list=failed.list
749                 ;;
750         conflict )
751                 grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" 2> /dev/null \
752                         | grep -q -E "^${origin_esc}[[:space:]]"
753                 return
754                 ;;
755         taboo )
756                 list=taboo.all.list
757                 ;;
758         freeze )
759                 list=freeze.all.list
760                 ;;
761         need )
762                 list=need.list
763                 ;;
764         noneed )
765                 list=noneed.list
766                 ;;
767         restored )
768                 list=stage.loop_list/ports_to_restore
769                 ;;
770         deleted )
771                 list=stage.loop_list/ports_to_delete
772                 ;;
773         esac
774         grep -q -Fx "$origin" "${DBDIR}/$list" 2> /dev/null
775 }
776
777 # ============= Check whether the requirements of installed packages match the port configuration =============
778 database_query_dependency_matching ()
779 {
780         local origin pkg tmp_inst tmp_db
781         origin=$1
782         [ -d "${DBDIR}/requires/$origin" ] || return
783         tmp_inst=${TMPDIR}/database_query_dependency_matching.installed
784         tmp_db=${TMPDIR}/database_query_dependency_matching.configured
785         pkg=`database_build_get_new_pkgname "$origin"`
786         [ -n "$pkg" ] || return
787         pkg_info_e "$pkg" || return
788         pkg_info_qr "$pkg" | grep -v '^[[:space:]]*$' | sort -u > $tmp_inst
789         database_build_get_full_run_requirement_pkgs "$origin" > $tmp_db
790         diff "$tmp_inst" "$tmp_db" > /dev/null 2>/dev/null
791 }
792
793 # ============= Check whether any of the requirements are locked because being missing ports to freeze =============
794 database_query_are_requirements_not_locked ()
795 {
796         local origin
797         origin=$1
798         cat "${DBDIR}/requires/$origin/requirements.all.direct" 2> /dev/null | while read origin_requirement
799         do
800                 pkg_requirement=`pkgsys_get_installed_pkg_from_origin "$origin_requirement"` || :
801                 if grep -q -Fx "$origin_requirement" "${DBDIR}/freeze.all.list" 2> /dev/null
802                 then
803                         [ -n "$pkg_requirement" ] || return
804                 elif [ -z "$pkg_requirement" ]
805                 then
806                         database_query_are_requirements_not_locked "$origin_requirement" || return
807                 fi
808         done
809         :
810 }
811
812 # ============= Check whether any of progress is made in the current run =============
813 database_query_is_any_progress ()
814 {
815         [ `cat "${DBDIR}/new_success_in_current_run" 2> /dev/null | wc -l` -gt 0 ]
816 }
817
818 # ============= Get the all initial origins, separated by line feed =============
819 database_query_initial_orgins ()
820 {
821         local origin origin_init
822         origin=$1
823         if [ -e "${DBDIR}/moved_from/$origin/old_origs" ]
824         then
825                 for origin_init in `cat "${DBDIR}/moved_from/$origin/old_origs"`
826                 do
827                         [ -e "${DBDIR}/initial/$origin_init/installed_version" ] && echo "$origin_init"
828                 done
829         else
830                 [ -e "${DBDIR}/initial/$origin/installed_version" ] && echo "$origin"
831         fi
832         :
833 }