OSDN Git Service

Fixed a syntax error.
[portsreinstall/current.git] / lib / libdatabase_query.sh
index 622c7b7..4ced7ce 100644 (file)
@@ -2,35 +2,42 @@
 # ==============================================================================
 # portsreinstall library script
 # - Operations for queries to the temporary database -
-# Copyright (C) 2013 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
+# Copyright (C) 2013-2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
 # This software is distributed under the 2-Clause BSD License.
 # ==============================================================================
 
 # ============= Show a list of failed ports with their reasons =============
 database_query_show_list_failure ()
 {
+       local tmp_valid
+       tmp_valid=${TMPDIR}/database_query_show_list_failure:valid
        if [ `cat "${DBDIR}/failed.list" 2> /dev/null | wc -l` -eq 0 ]
        then
                message_echo "INFO: No item is registered in this list."
                return 1
        fi
-       grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern" "${DBDIR}/failed.list" \
+       grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern" "${DBDIR}/failed.list" 2> /dev/null \
                | while read origin
        do
-               origin_regexp=`str_escape_regexp "$origin"`
-               grep -q -E "^$origin_regexp$" "${DBDIR}/stage.loop_list/ports_to_delete" 2> /dev/null \
-                       && continue
-               note=`cat "${DBDIR}/notes/$origin/note_failtre" 2> /dev/nul || :`
+               grep -q -Fx "$origin" "${DBDIR}/stage.loop_list/ports_to_delete" 2> /dev/null \
+                       || echo "$origin"
+       done > $tmp_valid
+       if [ `cat "$tmp_valid" 2> /dev/null | wc -l` -eq 0 ]
+       then
+               message_echo "INFO: No valid item is registered in this list."
+               return 1
+       fi
+       while read origin
+       do
+               note=`cat "${DBDIR}/notes/$origin/note_failtre" 2> /dev/null || :`
                resolved=no
-               grep -q -E "^`str_escape_regexp \"$origin\"`$" \
-                       "${DBDIR}/manually_done.list" 2> /dev/null \
-                       && resolved=yes
-               pkgtag=`cat "${DBDIR}/requires/$origin/pkgtag" 2> /dev/null || :`
+               grep -q -Fx "$origin" "${DBDIR}/manually_done.list" 2> /dev/null && resolved=yes
+               pkgtag=`cat "${DBDIR}/moved_from/$origin/pkgtag" 2> /dev/null || :`
                if [ $opt_batch_mode = no ]
                then
                        case $resolved in
-                       no    resolved=;;
-                       yes   resolved=', resolved';;
+                       no )    resolved=;;
+                       yes )   resolved=', resolved';;
                        esac
                        if [ -n "$note" ]
                        then
@@ -47,11 +54,11 @@ database_query_show_list_failure ()
                else
                        printf "%s\t%s\t%s\t%s\n" "$origin" "$pkgtag" "$note" "$resolved"
                fi
-       done
+       done < $tmp_valid
        :
 }
 
-# ============= Show a list of failed restoration of conflicts =============
+# ============= Show a list of failed restoration of conflict =============
 database_query_show_list_failed_conflicts_restoration ()
 {
        if [ `cat "${DBDIR}/deleted_conflicts" 2> /dev/null | wc -l` -eq 0 ]
@@ -63,7 +70,7 @@ database_query_show_list_failed_conflicts_restoration ()
                | while read origin pkg
                do
                        pkg_regexp=`str_escape_regexp "$pkg"`
-                       against=`grep -E "^$pkg_regexp:" "${DBDIR}/forbidden_conflicts" 2> /dev/null | cut -d : -f 2 | sort -u`
+                       against=`grep -E "^$pkg_regexp:" "${DBDIR}/forbidden_conflicts" 2> /dev/null | cut -d : -f 2,3 | sort -u`
                        if [ $opt_batch_mode = no ]
                        then
                                if [ -n "$pkg" ]
@@ -75,28 +82,42 @@ database_query_show_list_failed_conflicts_restoration ()
                                if [ -n "$against" ]
                                then
                                        echo -n " against "
-                                       against=`echo "$against" | tr '\n' ' '`
+                                       against=`echo "$against" | sed 's/:/(/;s/$/)/' | tr '\n' ' '`
                                        str_linearize_list_and "$against"
                                else
                                        echo
                                fi
                        else
-                               against=`echo "$against" | tr '\n' , | sed 's/,$//'`
+                               against=`echo "$against" | tr '\n' '|' | sed 's/,$//'`
                                printf '%s\t%s\t%s\n' "$origin" "$pkg" "$against"
                        fi
                done
        :
 }
 
-# ============= Insert initial origins to a list of origins =============
+# ============= Show installed ports which have been neither upgraded or reinstalled from the initial state =============
+database_query_show_list_fossil ()
+{
+       local srclist origin pkg
+       srclist=`ls "${DBDIR}"/fossil_pkgs/fossil_since_* | head -n 1`
+       [ -e "$srclist" ] || return 0
+       while read origin
+       do
+               pkg=`pkgsys_get_init_pkg_from_orig "$origin"`
+               pkg_info_e "$pkg" || continue
+               printf '%s\t%s\n' "$origin" "$pkg"
+       done < $srclist
+}
+
+# ============= Insert initial flavored origins to a list of flavored origins =============
 database_query_add_initial_origins ()
 {
        local origin
        while read origin
        do
                echo "$origin"
-               [ -e "${DBDIR}/requires/$origin/initial_orig" ] || continue
-               cat "${DBDIR}/requires/$origin/initial_orig"
+               [ -e "${DBDIR}/moved_from/$origin/initial_orig" ] || continue
+               cat "${DBDIR}/moved_from/$origin/initial_orig"
        done
        :
 }
@@ -142,20 +163,17 @@ database_query_get_target_attributes ()
 # ============= Check whether (re/de)installation of a port is suppressed =============
 database_query_is_a_port_suppressed ()
 {
-       local origin flag
+       local origin flags flag
        origin=$1
-       if [ $opt_suppress_self_upadte = yes ]
-       then
-               flag=SUPPRESSED_SELF
-       elif [ $opt_suppress_pkgtools_upadte = yes ]
-       then
-               flag=SUPPRESSED_PKGNG
-       else
-               return 1
-       fi
-       for db in initial requires
+       flags=
+       [ $opt_suppress_self_upadte = yes ] && flags=SUPPRESSED_SELF
+       [ $opt_suppress_pkgtools_upadte = yes ] && flags="$flags SUPPRESSED_PKGNG"
+       for flag in $flags
        do
-               [ -e "${DBDIR}/$db/$origin/$flag" ] && return
+               for db in initial moved_from
+               do
+                       [ -e "${DBDIR}/$db/$origin/$flag" ] && return
+               done
        done
        return 1
 }
@@ -163,12 +181,15 @@ database_query_is_a_port_suppressed ()
 # ============= Check whether a port needs to be updated or upgraded =============
 database_query_does_a_port_need_update ()
 {
-       local origin dbpath
+       local origin dbpath frompath new_version current_version
        origin=$1
        dbpath=${DBDIR}/requires/$origin
+       frompath=${DBDIR}/moved_from/$origin
        [ -e "$dbpath/conf_updated" ] && return
        [ -e "$dbpath/new_version" ] || return
-       ! diff "$dbpath/new_version" "$dbpath/current_version" > /dev/null 2>&1
+       new_version=`cat "$dbpath/new_version"`
+       current_version=`cat "$frompath/current_version"`
+       [ "x$current_version" != "x$new_version" ]
 }
 
 # ============= Check before operations of a command which need the temporary database completely prepared =============
@@ -202,10 +223,20 @@ database_query_get_makevar_val ()
        fi
 }
 
+# ============= Get a configured value of a port =============
+database_query_get_config_val ()
+{
+       local origin variable dbdir cache value
+       origin=$1
+       variable=$2
+       dbfile=${DBDIR}/conf/each_port/$origin/$variable.conf
+       cat "$dbfile" 2> /dev/null || :
+}
+
 # ============= Check whether configurations for a port is default =============
 database_query_is_default_conf ()
 {
-       local origin mode dbpath tmp_msg is_customized is_requiremnt_replaced files origin_regexp tmp_old tmp_new origin_requirement
+       local origin mode dbpath tmp_msg is_customized is_requiremnt_replaced files tmp_old tmp_new origin_requirement tmp_msg_customized
        origin=$1
        mode=$2
        dbpath=${DBDIR}/requires/$origin
@@ -216,17 +247,16 @@ database_query_is_default_conf ()
                is_customized=no
                if [ `ls "${DBDIR}/conf/each_port/$origin" 2> /dev/null | wc -l` -gt 0 ]
                then
-                       files=`ls "${DBDIR}/conf/each_port/$origin" | str_cancat_items_for_sentence`
+                       files=`ls "${DBDIR}/conf/each_port/$origin" | sed -E 's/^([^.]+).*/\1/' | str_concat_items_for_sentence`
                        echo "Knobs and miscellaneous customization by $files," >> $tmp_msg
                        is_customized=yes
                fi
-               if ! diff "$dbpath/ports_options.default" "$dbpath/ports_options.current" > /dev/null 2>&1
+               if ! diff -q "$dbpath/ports_options.default" "$dbpath/ports_options.current" > /dev/null 2>&1
                then
                        echo "Non-default port options," >> $tmp_msg
                        is_customized=yes
                fi
-               origin_regexp=`str_escape_regexp "$origin"`
-               if grep -q -E "^$origin_regexp$" "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null
+               if grep -q -Fx "$origin" "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null
                then
                        echo "Explicit specification as non-default in ${APPNAME}.conf," >> $tmp_msg
                        is_customized=yes
@@ -257,17 +287,17 @@ database_query_is_default_conf ()
        [ `wc -c < $dbpath/is_customized` -eq 0 ] && return
        if [ "x$mode" != xquiet ]
        then
+               tmp_msg_customized=${TMPDIR}/database_query_is_default_conf:msg_customized
                message_echo "INFO: This port is configured to be non-default because of"
-               message_cat 3<< eof
-`sed 's/^/         /' "$dbpath/is_customized"`
-eof
+               sed 's/^/         /' "$dbpath/is_customized" > $tmp_msg_customized
+               message_cat "$tmp_msg_customized"
                message_echo "      so the prebuilt package is not used."
        fi
        return 1
 }
 
 # ============= Output of lists in which each matching port is registered =============
-database_query_for_list_inclusion_of_matching_port ()
+database_query_show_list_inclusion_of_matching_port ()
 {
        local grandtitle lists pkgnamedb deptag level isfirst origin_target pkg_target table_target
        grandtitle=$1
@@ -277,7 +307,7 @@ database_query_for_list_inclusion_of_matching_port ()
        level=$5
        shift 5
        message_echo "[$grandtitle]"
-       message_dependency_scope
+       message_dependency_scope "$deptag" "$level"
        message_echo
        isfirst=y
        for origin_target in `pkgsys_eval_ports_glob "$@"`
@@ -313,20 +343,20 @@ database_query_for_list_inclusion_of_matching_port ()
        :
 }
 
-
-# ============= Output of "show" command for each matching port =============
-database_query_for_each_matching_port ()
+# ============= Output of "show" command for port lists =============
+database_query_show_port_lists ()
 {
-       local grandtitle title list pkgnamedb deptag level isfirst origin_target pkg_target table_target list_target
+       local grandtitle title list listdb pkgnamedb deptag level isfirst origin_target pkg_target table_target list_target
        grandtitle=$1
        title=$2
        list=$3
-       pkgnamedb=$4
-       deptag=$5
-       level=$6
-       shift 6
+       listdb=$4
+       pkgnamedb=$5
+       deptag=$6
+       level=$7
+       shift 7
        message_echo "[$grandtitle]"
-       message_dependency_scope
+       message_dependency_scope "$deptag" "$level"
        message_echo
        isfirst=y
        for origin_target in `pkgsys_eval_ports_glob "$@"`
@@ -342,7 +372,7 @@ database_query_for_each_matching_port ()
                isfirst=n
                [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
                list_target=
-               for table_target in $pkgnamedb
+               for table_target in $listdb
                do
                        list_target=${DBDIR}/$table_target/$origin_target/$list
                        [ -e "$list_target" ] && break
@@ -383,39 +413,150 @@ database_query_for_each_matching_port ()
        :
 }
 
+# ============= Output of "show" command for log files =============
+database_query_show_log ()
+{
+       local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
+       grandtitle=$1
+       title=$2
+       list=$3
+       listdb=$4
+       pkgnamedb=$5
+       shift 5
+       message_echo "[$grandtitle]"
+       message_echo
+       isfirst=y
+       for origin_target in `pkgsys_eval_ports_glob "$@"`
+       do
+               pkg_target=
+               for table_target in $pkgnamedb
+               do
+                       pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
+                       [ -n "$pkg_target" ] && break
+               done
+               [ -n "$pkg_target" ] || continue
+               [ "$isfirst" = y ] || message_echo
+               isfirst=n
+               [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
+               list_target=
+               for table_target in $listdb
+               do
+                       list_target=${DBDIR}/$table_target/$origin_target/$list
+                       [ -e "$list_target" ] && break
+               done
+               [ -e "$list_target" ] || continue
+               cat  < $list_target
+               echo
+       done
+       if [ "$isfirst" = y ]
+       then
+               message_echo "ERROR: No inspected port matches the glob(s)." >&2
+               exit 1
+       fi
+       :
+}
+
+# ============= Output of "show" command for two column lists =============
+database_query_show_two_column_lists ()
+{
+       local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
+       grandtitle=$1
+       title=$2
+       list=$3
+       listdb=$4
+       pkgnamedb=$5
+       shift 5
+       message_echo "[$grandtitle]"
+       message_echo
+       isfirst=y
+       for origin_target in `pkgsys_eval_ports_glob "$@"`
+       do
+               pkg_target=
+               for table_target in $pkgnamedb
+               do
+                       pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
+                       [ -n "$pkg_target" ] && break
+               done
+               [ -n "$pkg_target" ] || continue
+               [ "$isfirst" = y ] || message_echo
+               isfirst=n
+               [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
+               list_target=
+               for table_target in $listdb
+               do
+                       list_target=${DBDIR}/$table_target/$origin_target/$list
+                       [ -e "$list_target" ] && break
+               done
+               [ -e "$list_target" ] || continue
+               if [ $opt_batch_mode = no ]
+               then
+                       sed 's/[[:space:]]/: /' < $list_target
+               else
+                       cat  < $list_target
+               fi
+       done
+       if [ "$isfirst" = y ]
+       then
+               message_echo "ERROR: No inspected port matches the glob(s)." >&2
+               exit 1
+       fi
+       :
+}
+
 # ============= Output of "show" command for a single list =============
 database_query_show_single_list ()
 {
-       local list pkgnamedb flag_filter_skip_unchanged flag_filter_only_target tmpflag_exists put_blankline
+       local list pkgnamedb flag_filter_skip_unchanged flag_filter_only_target flag_negative_listdb tmpflag_exists put_blankline origin matches flag pkg table
+       local currentorigin_is_alll currentorigin_is_target currentorigin_is_requires_requirements
+       local currentorigin_is_initial_requirements currentorigin_is_requires_dependents
+       local currentorigin_is_initial_dependents currentorigin_is_requires_requirements_complement currentorigin_is_relevant
        list=$1
        pkgnamedb=$2
        flag_filter_skip_unchanged=$3
        flag_filter_only_target=$4
+       flag_negative_listdb=$5
        tmpflag_exists=${TMPDIR}/database_query_show_single_list::exists_item
        if [ `cat "${DBDIR}/$list" 2> /dev/null | wc -l` -eq 0 ]
        then
                message_echo "INFO: No item is registered in this list."
                return 1
        fi
+       if ! program_chk_stage_complete PREPARATION
+       then
+               message_echo "WARNING: The temporary database is incomplete. The raw list is shown." >&2
+               cat "${DBDIR}/$list"
+               return
+       fi
        rm -f "$tmpflag_exists"
        put_blankline=
        if [ -n "$flag_filter_only_target" \
                -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
        then
-               message_echo "INFO: Ports outside of the target scope are excluded."
+               message_echo "WARNING: Ports outside of the target scope are excluded." >&2
                put_blankline=y
        fi
        if [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes ]
        then
-               message_echo "INFO: Ports which have been the newest with their all requirements from the first are excluded."
+               message_echo "WARNING: Ports which have been the newest with their all requirements from the first are excluded." >&2
                put_blankline=y
        fi
        [ -n "$put_blankline" ] && message_echo
        while read origin
        do
-               [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes \
-                       -a ! -e "${DBDIR}/requires/$origin/$flag_filter_skip_unchanged" ] \
-                       && continue
+               [ -n "$flag_negative_listdb" ] && grep -Fx "$origin" "${DBDIR}/$flag_negative_listdb" 2> /dev/null && continue
+               if [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes ]
+               then
+                       matches=no
+                       for flag in $flag_filter_skip_unchanged
+                       do
+                               if [ -e "${DBDIR}/requires/$origin/$flag" ]
+                               then
+                                       matches=yes
+                                       break
+                               fi
+                       done
+                       [ $matches = no ] && continue
+               fi
                if [ -n "$flag_filter_only_target" ]
                then
                        database_query_get_target_attributes currentorigin "$origin"
@@ -459,99 +600,193 @@ database_query_is_necessary_upgrade ()
        fileedit_exists_old_lines "$tmpfile_old" "$tmpfile_new"
 }
 
+# ============= Show moved or replaced ports to alternatives =============
+database_query_show_list_moved ()
+{
+       cat "${DBDIR}/moved_ports" 2> /dev/null | while read origin
+       do
+               lastorigin=$origin
+               while [ -n "$lastorigin" -a -e "${DBDIR}/replace/$lastorigin/origin" ]
+               do
+                       lastorigin=`cat "${DBDIR}/replace/$lastorigin/origin"`
+               done
+               [ -n "$lastorigin" ] || continue
+               pkg=
+               for table in $pkgnamedb
+               do
+                       pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
+                       [ -n "$pkg" ] && break
+               done
+               [ -n "$pkg" ] || pkg='not installed'
+               lastpkg=
+               for table in moved_from obsolete initial
+               do
+                       lastpkg=`cat "${DBDIR}/$table/$lastorigin/pkgtag" 2> /dev/null` || :
+                       [ -n "$lastpkg" ] && break
+               done
+               [ -n "$lastpkg" ] || lastpkg='not installed'
+               if [ $opt_batch_mode = no ]
+               then
+                       echo "$origin ($pkg) => $lastorigin ($lastpkg)"
+               else
+                       printf '%s\t%s\t%s\t%s\n' "$origin" "$pkg" "$lastorigin" "$lastpkg"
+               fi
+       done
+}
+
 # ============= Actual operations of "show" command for a single list =============
 database_query_show_single_list_exec ()
 {
-       local subject deptag level dbsuffix flag_filter_skip_unchanged flag_filter_only_target pkgnamedb
+       local subject deptag level dbsuffix flag_filter_skip_unchanged flag_filter_only_target flag_negative_listdb pkgnamedb
        subject=$1
        deptag=$2
        level=$3
        dbsuffix=$deptag.$level
        flag_filter_skip_unchanged=
        flag_filter_only_target=
-       pkgnamedb='requires obsolete initial'
+       flag_negative_listdb=
+       pkgnamedb='moved_from obsolete initial'
        case $subject in
-       todo)
+       todo )
                message_echo "The following ports remain in the (re)installation queue for the current do/redo process:"
                message_echo "It is noted that ports to be skipped can be included here."
-               message_dependency_scope
+               message_dependency_scope "$deptag" "$level"
                message_echo
                list=stage.loop_list/reinst_todo.remain
                [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
                flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
                flag_filter_only_target=y
                ;;
-       done)
+       done )
                message_echo "The following ports have been successfully (re)installed or newly installed:"
-               message_dependency_scope
+               message_dependency_scope "$deptag" "$level"
                message_echo
                list=success.$dbsuffix.list
                flag_filter_skip_unchanged=necessary_upgrade_completed.$dbsuffix
                flag_filter_only_target=y
                ;;
-       redo)
-               message_echo "The following ports need (re)installation but are to be skipped until any of their failed requirements succeeds:"
-               message_dependency_scope
+       redo )
+               message_echo "The following ports need (re)installation after success of the all requirements:"
+               message_dependency_scope "$deptag" "$level"
                message_echo
                list=todo_after_requirements_succeed.$dbsuffix.list
-               flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
+               flag_filter_skip_unchanged="necessary_upgrade.$dbsuffix necessary_upgrade_completed.$dbsuffix"
                flag_filter_only_target=y
+               flag_negative_listdb=leaf_ports_to_delete.unselected
                ;;
-       resolved)
+       resolved )
                message_echo "The following ports had problems which have been manually resolved:"
                message_echo
                list=manually_done.list
                ;;
-       failure)
+       inst_by_pkg )
+               message_echo "The following ports are configured default and installed by prebuilt packages"
+               message_echo
+               list=installation_complete_by_pkg.list
+               ;;
+       inst_built_default )
+               message_echo "The following ports are configured default and installed by ports"
+               message_echo
+               list=inst_by_port_with_default_conf.list
+               ;;
+       inst_built_custom )
+               message_echo "The following ports are configured non-default and installed by ports"
+               message_echo
+               list=inst_by_port_with_custom_conf.list
+               ;;
+       failure )
                message_echo "The following ports experienced failures and kept to be old or uninstalled:"
                message_echo
                database_query_show_list_failure
                return
                ;;
-       conflict)
-               message_echo "The following ports are temporarily deleted due to conflicts:"
+       fossil )
+               message_echo "The following ports are neither upgraded or reinstalled from the initial state:"
+               message_echo
+               database_query_show_list_fossil
+               return
+               ;;
+       conflict )
+               message_echo "The following ports are temporarily deleted due to conflict:"
                message_echo
                database_query_show_list_failed_conflicts_restoration
                return
                ;;
-       taboo)
+       moved )
+               message_echo "The following ports are moved/replaced to new alternatives:"
+               message_echo
+               database_query_show_list_moved
+               return
+               ;;
+       taboo )
                message_echo "The following ports are registered as taboo:"
                message_echo
                list=taboo.all.list
                ;;
-       need)
+       freeze )
+               message_echo "The following ports are registered to freeze:"
+               message_echo
+               list=freeze.all.list
+               ;;
+       need )
                message_echo "The following ports are registered as necessary:"
                message_echo
                list=need.list
                ;;
-       noneed)
+       noneed )
                message_echo "The following ports are registered as unnecessary:"
                message_echo
                list=noneed.list
                ;;
-       restored)
+       restored )
                message_echo "The following leaf, obsolete or unneeded ports had been once deleted but are to be or have been restored:"
                message_echo
                list=stage.loop_list/ports_to_restore
-               pkgnamedb='obsolete initial'
+               pkgnamedb='moved_from obsolete initial'
                flag_filter_only_target=y
                ;;
-       deleted)
+       deleted )
                message_echo "The following leaf, obsolete or unneeded ports are to be or have been deleted:"
                message_echo
                list=stage.loop_list/ports_to_delete
-               pkgnamedb='obsolete initial'
+               pkgnamedb='moved_from obsolete initial'
+               flag_filter_only_target=y
+               ;;
+       leaves )
+               if [ -z "$deptag" ]
+               then
+                       message_echo "The following ports are all detected leaf ports:"
+                       list=leaf_ports
+               else
+                       message_echo "The following ports are all $deptag leaf ports:"
+                       list=leaf_ports_to_delete.$deptag
+               fi
+               message_echo
+               pkgnamedb='moved_from obsolete initial'
+               flag_filter_only_target=y
+               ;;
+       obsolete )
+               if [ -z "$deptag" ]
+               then
+                       message_echo "The following ports are all detected obsolete ports:"
+                       list=obsolete_ports.can_be_deleted
+               else
+                       message_echo "The following ports are all $deptag obsolete ports:"
+                       list=obsolete_ports_to_delete.$deptag
+               fi
+               message_echo
+               pkgnamedb='moved_from obsolete initial'
                flag_filter_only_target=y
                ;;
        esac
        database_query_show_single_list "$list" "$pkgnamedb" \
-               "$flag_filter_skip_unchanged" "$flag_filter_only_target"
+               "$flag_filter_skip_unchanged" "$flag_filter_only_target" "$flag_negative_listdb"
 }
 
 # ============= Check whether a port is registered in a list =============
 database_query_exists_in_list ()
 {
-       local origin subject deptag level tmp_list dbsuffix origin_esc origin_ptn
+       local origin subject deptag level tmp_list dbsuffix origin_esc
        origin=$1
        subject=$2
        deptag=$3
@@ -559,44 +794,116 @@ database_query_exists_in_list ()
        tmp_list=${TMPDIR}/database_query_exists_in_list:list
        dbsuffix=$deptag.$level
        origin_esc=`str_escape_regexp "$origin"`
-       origin_ptn="^$origin_esc$"
        case $subject in
-       todo)
+       todo )
                list=stage.loop_list/reinst_todo.remain
                [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
                ;;
-       done)
+       done )
                list=success.$dbsuffix.list
                ;;
-       redo)
+       redo )
                list=todo_after_requirements_succeed.$dbsuffix.list
                ;;
-       resolved)
+       resolved )
                list=manually_done.list
                ;;
-       failure)
+       inst_by_pkg )
+               list=installation_complete_by_pkg.list
+               ;;
+       inst_built_default )
+               list=inst_by_port_with_default_conf.list
+               ;;
+       inst_built_custom )
+               list=inst_by_port_with_custom_conf.list
+               ;;
+       failure )
                list=failed.list
                ;;
-       conflict)
+       fossil )
+               list=`ls "${DBDIR}"/fossil_pkgs/fossil_since_* | head -n 1`
+               ;;
+       conflict )
                grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" 2> /dev/null \
                        | grep -q -E "^${origin_esc}[[:space:]]"
                return
                ;;
-       taboo)
+       taboo )
                list=taboo.all.list
                ;;
-       need)
+       freeze )
+               list=freeze.all.list
+               ;;
+       need )
                list=need.list
                ;;
-       noneed)
+       noneed )
                list=noneed.list
                ;;
-       restored)
+       restored )
                list=stage.loop_list/ports_to_restore
                ;;
-       deleted)
+       deleted )
                list=stage.loop_list/ports_to_delete
                ;;
        esac
-       grep -q -E "$origin_ptn" "${DBDIR}/$list" 2> /dev/null
+       grep -q -Fx "$origin" "${DBDIR}/$list" 2> /dev/null
+}
+
+# ============= Check whether the requirements of installed packages match the port configuration =============
+database_query_dependency_matching ()
+{
+       local origin pkg tmp_inst tmp_db
+       origin=$1
+       [ -d "${DBDIR}/requires/$origin" ] || return
+       tmp_inst=${TMPDIR}/database_query_dependency_matching.installed
+       tmp_db=${TMPDIR}/database_query_dependency_matching.configured
+       pkg=`database_build_get_new_pkgname "$origin"`
+       [ -n "$pkg" ] || return
+       pkg_info_e "$pkg" || return
+       pkg_info_qr "$pkg" | grep -v '^[[:space:]]*$' | sort -u > $tmp_inst
+       database_build_get_full_run_requirement_pkgs "$origin" > $tmp_db
+       diff "$tmp_inst" "$tmp_db" > /dev/null 2>/dev/null
+}
+
+# ============= Check whether any of the requirements are locked because being missing ports to freeze =============
+database_query_are_requirements_not_locked ()
+{
+       local origin
+       origin=$1
+       cat "${DBDIR}/requires/$origin/requirements.all.direct" 2> /dev/null | while read origin_requirement
+       do
+               pkg_requirement=`pkgsys_get_installed_pkg_from_origin "$origin_requirement"` || :
+               if grep -q -Fx "$origin_requirement" "${DBDIR}/freeze.all.list" 2> /dev/null
+               then
+                       [ -n "$pkg_requirement" ] || return
+               elif [ -z "$pkg_requirement" ]
+               then
+                       database_query_are_requirements_not_locked "$origin_requirement" || return
+               fi
+       done
+       :
+}
+
+# ============= Check whether any of progress is made in the current run =============
+database_query_is_any_progress ()
+{
+       [ `cat "${DBDIR}/new_success_in_current_run" 2> /dev/null | wc -l` -gt 0 ]
+}
+
+# ============= Get the all initial origins, separated by line feed =============
+database_query_initial_orgins ()
+{
+       local origin origin_init
+       origin=$1
+       if [ -e "${DBDIR}/moved_from/$origin/old_origs" ]
+       then
+               for origin_init in `cat "${DBDIR}/moved_from/$origin/old_origs"`
+               do
+                       [ -e "${DBDIR}/initial/$origin_init/installed_version" ] && echo "$origin_init"
+               done
+       else
+               [ -e "${DBDIR}/initial/$origin/installed_version" ] && echo "$origin"
+       fi
+       :
 }