OSDN Git Service

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