OSDN Git Service

[NEW] show inst_by_pkg 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 "$deptag" "$level"
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 deptag level 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         deptag=$6
342         level=$7
343         shift 7
344         message_echo "[$grandtitle]"
345         message_dependency_scope "$deptag" "$level"
346         message_echo
347         isfirst=y
348         for origin_target in `pkgsys_eval_ports_glob "$@"`
349         do
350                 pkg_target=
351                 for table_target in $pkgnamedb
352                 do
353                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
354                         [ -n "$pkg_target" ] && break
355                 done
356                 [ -n "$pkg_target" ] || continue
357                 [ "$isfirst" = y ] || message_echo
358                 isfirst=n
359                 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
360                 list_target=
361                 for table_target in $listdb
362                 do
363                         list_target=${DBDIR}/$table_target/$origin_target/$list
364                         [ -e "$list_target" ] && break
365                 done
366                 [ -e "$list_target" ] || continue
367                 if [ $opt_batch_mode = no ]
368                 then
369                         while read origin
370                         do
371                                 pkg=
372                                 for table in $pkgnamedb
373                                 do
374                                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
375                                         [ -n "$pkg" ] && break
376                                 done
377                                 [ -n "$pkg" ] || continue
378                                 echo "$origin ($pkg)"
379                         done < $list_target
380                 else
381                         while read origin
382                         do
383                                 pkg=
384                                 for table in $pkgnamedb
385                                 do
386                                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
387                                         [ -n "$pkg" ] && break
388                                 done
389                                 [ -n "$pkg" ] || continue
390                                 printf '%s\t%s\t%s\t%s\n' "$origin_target" "$pkg_target" "$origin" "$pkg"
391                         done < $list_target
392                 fi
393         done
394         if [ "$isfirst" = y ]
395         then
396                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
397                 exit 1
398         fi
399         :
400 }
401
402 # ============= Output of "show" command for log files =============
403 database_query_show_log ()
404 {
405         local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
406         grandtitle=$1
407         title=$2
408         list=$3
409         listdb=$4
410         pkgnamedb=$5
411         shift 5
412         message_echo "[$grandtitle]"
413         message_echo
414         isfirst=y
415         for origin_target in `pkgsys_eval_ports_glob "$@"`
416         do
417                 pkg_target=
418                 for table_target in $pkgnamedb
419                 do
420                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
421                         [ -n "$pkg_target" ] && break
422                 done
423                 [ -n "$pkg_target" ] || continue
424                 [ "$isfirst" = y ] || message_echo
425                 isfirst=n
426                 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
427                 list_target=
428                 for table_target in $listdb
429                 do
430                         list_target=${DBDIR}/$table_target/$origin_target/$list
431                         [ -e "$list_target" ] && break
432                 done
433                 [ -e "$list_target" ] || continue
434                 cat  < $list_target
435                 echo
436         done
437         if [ "$isfirst" = y ]
438         then
439                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
440                 exit 1
441         fi
442         :
443 }
444
445 # ============= Output of "show" command for two column lists =============
446 database_query_show_two_column_lists ()
447 {
448         local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
449         grandtitle=$1
450         title=$2
451         list=$3
452         listdb=$4
453         pkgnamedb=$5
454         shift 5
455         message_echo "[$grandtitle]"
456         message_echo
457         isfirst=y
458         for origin_target in `pkgsys_eval_ports_glob "$@"`
459         do
460                 pkg_target=
461                 for table_target in $pkgnamedb
462                 do
463                         pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
464                         [ -n "$pkg_target" ] && break
465                 done
466                 [ -n "$pkg_target" ] || continue
467                 [ "$isfirst" = y ] || message_echo
468                 isfirst=n
469                 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
470                 list_target=
471                 for table_target in $listdb
472                 do
473                         list_target=${DBDIR}/$table_target/$origin_target/$list
474                         [ -e "$list_target" ] && break
475                 done
476                 [ -e "$list_target" ] || continue
477                 if [ $opt_batch_mode = no ]
478                 then
479                         sed 's/[[:space:]]/: /' < $list_target
480                 else
481                         cat  < $list_target
482                 fi
483         done
484         if [ "$isfirst" = y ]
485         then
486                 message_echo "ERROR: No inspected port matches the glob(s)." >&2
487                 exit 1
488         fi
489         :
490 }
491
492 # ============= Output of "show" command for a single list =============
493 database_query_show_single_list ()
494 {
495         local list pkgnamedb flag_filter_skip_unchanged flag_filter_only_target tmpflag_exists put_blankline
496         list=$1
497         pkgnamedb=$2
498         flag_filter_skip_unchanged=$3
499         flag_filter_only_target=$4
500         tmpflag_exists=${TMPDIR}/database_query_show_single_list::exists_item
501         if [ `cat "${DBDIR}/$list" 2> /dev/null | wc -l` -eq 0 ]
502         then
503                 message_echo "INFO: No item is registered in this list."
504                 return 1
505         fi
506         if ! program_chk_stage_complete PREPARATION
507         then
508                 message_echo "WARNING: The temporary database is incomplete. The raw list is shown." >&2
509                 cat "${DBDIR}/$list"
510                 return
511         fi
512         rm -f "$tmpflag_exists"
513         put_blankline=
514         if [ -n "$flag_filter_only_target" \
515                 -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
516         then
517                 message_echo "WARNING: Ports outside of the target scope are excluded." >&2
518                 put_blankline=y
519         fi
520         if [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes ]
521         then
522                 message_echo "WARNING: Ports which have been the newest with their all requirements from the first are excluded." >&2
523                 put_blankline=y
524         fi
525         [ -n "$put_blankline" ] && message_echo
526         while read origin
527         do
528                 [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes \
529                         -a ! -e "${DBDIR}/requires/$origin/$flag_filter_skip_unchanged" ] \
530                         && continue
531                 if [ -n "$flag_filter_only_target" ]
532                 then
533                         database_query_get_target_attributes currentorigin "$origin"
534                         [ -n "${currentorigin_is_relevant}" ] || continue
535                         database_query_is_a_port_suppressed "$origin" && continue
536                 fi
537                 pkg=
538                 for table in $pkgnamedb
539                 do
540                         pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
541                         [ -n "$pkg" ] && break
542                 done
543                 [ -n "$pkg" ] || continue
544                 touch "$tmpflag_exists"
545                 if [ $opt_batch_mode = no ]
546                 then
547                         echo "$origin ($pkg)"
548                 else
549                         printf '%s\t%s\n' "$origin" "$pkg"
550                 fi
551         done < ${DBDIR}/$list
552         [ -e "$tmpflag_exists" ] && return
553         message_echo "INFO: No item is registered in this list."
554         return 1
555 }
556
557 # ============= Check whether the upgrade is necessary for a port =============
558 database_query_is_necessary_upgrade ()
559 {
560         local origin nodedir dbsuffix tmpfile_new tmpfile_old tmpfile_diff
561         origin=$1
562         nodedir=${DBDIR}/requires/$origin
563         [ -e "$nodedir/installed_by_pkg" ] && return 1
564         dbsuffix=`options_get_dependency_type`.`options_get_dependency_level`
565         tmpfile_new=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.new
566         tmpfile_old=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.old
567         tmpfile_diff=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.diff
568         [ -e "$nodedir/failed_requirements.${dbsuffix}.previous" ] || return
569         sort -u "$nodedir/failed_requirements.${dbsuffix}" > $tmpfile_new 2> /dev/null || :
570         sort -u "$nodedir/failed_requirements.${dbsuffix}.previous" > $tmpfile_old 2> /dev/null || :
571         fileedit_exists_old_lines "$tmpfile_old" "$tmpfile_new"
572 }
573
574 # ============= Actual operations of "show" command for a single list =============
575 database_query_show_single_list_exec ()
576 {
577         local subject deptag level dbsuffix flag_filter_skip_unchanged flag_filter_only_target pkgnamedb
578         subject=$1
579         deptag=$2
580         level=$3
581         dbsuffix=$deptag.$level
582         flag_filter_skip_unchanged=
583         flag_filter_only_target=
584         pkgnamedb='moved_from obsolete initial'
585         case $subject in
586         todo )
587                 message_echo "The following ports remain in the (re)installation queue for the current do/redo process:"
588                 message_echo "It is noted that ports to be skipped can be included here."
589                 message_dependency_scope "$deptag" "$level"
590                 message_echo
591                 list=stage.loop_list/reinst_todo.remain
592                 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
593                 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
594                 flag_filter_only_target=y
595                 ;;
596         done )
597                 message_echo "The following ports have been successfully (re)installed or newly installed:"
598                 message_dependency_scope "$deptag" "$level"
599                 message_echo
600                 list=success.$dbsuffix.list
601                 flag_filter_skip_unchanged=necessary_upgrade_completed.$dbsuffix
602                 flag_filter_only_target=y
603                 ;;
604         redo )
605                 message_echo "The following ports need (re)installation but are to be skipped until any of their failed requirements succeeds:"
606                 message_dependency_scope "$deptag" "$level"
607                 message_echo
608                 list=todo_after_requirements_succeed.$dbsuffix.list
609                 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
610                 flag_filter_only_target=y
611                 ;;
612         resolved )
613                 message_echo "The following ports had problems which have been manually resolved:"
614                 message_echo
615                 list=manually_done.list
616                 ;;
617         inst_by_pkg )
618                 message_echo "The following ports are configured default and installed by prebuilt packages"
619                 message_echo
620                 list=installation_complete_by_pkg.list
621                 ;;
622         failure )
623                 message_echo "The following ports experienced failures and kept to be old or uninstalled:"
624                 message_echo
625                 database_query_show_list_failure
626                 return
627                 ;;
628         conflict )
629                 message_echo "The following ports are temporarily deleted due to conflict:"
630                 message_echo
631                 database_query_show_list_failed_conflicts_restoration
632                 return
633                 ;;
634         taboo )
635                 message_echo "The following ports are registered as taboo:"
636                 message_echo
637                 list=taboo.all.list
638                 ;;
639         freeze )
640                 message_echo "The following ports are registered to freeze:"
641                 message_echo
642                 list=freeze.all.list
643                 ;;
644         need )
645                 message_echo "The following ports are registered as necessary:"
646                 message_echo
647                 list=need.list
648                 ;;
649         noneed )
650                 message_echo "The following ports are registered as unnecessary:"
651                 message_echo
652                 list=noneed.list
653                 ;;
654         restored )
655                 message_echo "The following leaf, obsolete or unneeded ports had been once deleted but are to be or have been restored:"
656                 message_echo
657                 list=stage.loop_list/ports_to_restore
658                 pkgnamedb='moved_from obsolete initial'
659                 flag_filter_only_target=y
660                 ;;
661         deleted )
662                 message_echo "The following leaf, obsolete or unneeded ports are to be or have been deleted:"
663                 message_echo
664                 list=stage.loop_list/ports_to_delete
665                 pkgnamedb='moved_from obsolete initial'
666                 flag_filter_only_target=y
667                 ;;
668         leaves )
669                 if [ -z "$deptag" ]
670                 then
671                         message_echo "The following ports are all detected leaf ports:"
672                         list=leaf_ports
673                 else
674                         message_echo "The following ports are all $deptag leaf ports:"
675                         list=leaf_ports_to_delete.$deptag
676                 fi
677                 message_echo
678                 pkgnamedb='moved_from obsolete initial'
679                 flag_filter_only_target=y
680                 ;;
681         obsolete )
682                 if [ -z "$deptag" ]
683                 then
684                         message_echo "The following ports are all detected obsolete ports:"
685                         list=obsolete_ports.can_be_deleted
686                 else
687                         message_echo "The following ports are all $deptag obsolete ports:"
688                         list=obsolete_ports_to_delete.$deptag
689                 fi
690                 message_echo
691                 pkgnamedb='moved_from obsolete initial'
692                 flag_filter_only_target=y
693                 ;;
694         esac
695         database_query_show_single_list "$list" "$pkgnamedb" \
696                 "$flag_filter_skip_unchanged" "$flag_filter_only_target"
697 }
698
699 # ============= Check whether a port is registered in a list =============
700 database_query_exists_in_list ()
701 {
702         local origin subject deptag level tmp_list dbsuffix origin_esc
703         origin=$1
704         subject=$2
705         deptag=$3
706         level=$4
707         tmp_list=${TMPDIR}/database_query_exists_in_list:list
708         dbsuffix=$deptag.$level
709         origin_esc=`str_escape_regexp "$origin"`
710         case $subject in
711         todo )
712                 list=stage.loop_list/reinst_todo.remain
713                 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
714                 ;;
715         done )
716                 list=success.$dbsuffix.list
717                 ;;
718         redo )
719                 list=todo_after_requirements_succeed.$dbsuffix.list
720                 ;;
721         resolved )
722                 list=manually_done.list
723                 ;;
724         inst_by_pkg )
725                 list=installation_complete_by_pkg.list
726                 ;;
727         failure )
728                 list=failed.list
729                 ;;
730         conflict )
731                 grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" 2> /dev/null \
732                         | grep -q -E "^${origin_esc}[[:space:]]"
733                 return
734                 ;;
735         taboo )
736                 list=taboo.all.list
737                 ;;
738         freeze )
739                 list=freeze.all.list
740                 ;;
741         need )
742                 list=need.list
743                 ;;
744         noneed )
745                 list=noneed.list
746                 ;;
747         restored )
748                 list=stage.loop_list/ports_to_restore
749                 ;;
750         deleted )
751                 list=stage.loop_list/ports_to_delete
752                 ;;
753         esac
754         grep -q -Fx "$origin" "${DBDIR}/$list" 2> /dev/null
755 }
756
757 # ============= Check whether the requirements of installed packages match the port configuration =============
758 database_query_dependency_matching ()
759 {
760         local origin pkg tmp_inst tmp_db
761         origin=$1
762         [ -d "${DBDIR}/requires/$origin" ] || return
763         tmp_inst=${TMPDIR}/database_query_dependency_matching.installed
764         tmp_db=${TMPDIR}/database_query_dependency_matching.configured
765         pkg=`database_build_get_new_pkgname "$origin"`
766         [ -n "$pkg" ] || return
767         pkg_info_e "$pkg" || return
768         pkg_info_qr "$pkg" | grep -v '^[[:space:]]*$' | sort -u > $tmp_inst
769         database_build_get_full_run_requirement_pkgs "$origin" > $tmp_db
770         diff "$tmp_inst" "$tmp_db" > /dev/null 2>/dev/null
771 }
772
773 # ============= Check whether any of the requirements are locked because being missing ports to freeze =============
774 database_query_are_requirements_not_locked ()
775 {
776         local origin
777         origin=$1
778         cat "${DBDIR}/requires/$origin/requirements.all.direct" 2> /dev/null | while read origin_requirement
779         do
780                 pkg_requirement=`pkgsys_get_installed_pkg_from_origin "$origin_requirement"` || :
781                 if grep -q -Fx "$origin_requirement" "${DBDIR}/freeze.all.list" 2> /dev/null
782                 then
783                         [ -n "$pkg_requirement" ] || return
784                 elif [ -z "$pkg_requirement" ]
785                 then
786                         database_query_are_requirements_not_locked "$origin_requirement" || return
787                 fi
788         done
789         :
790 }
791
792 # ============= Check whether any of progress is made in the current run =============
793 database_query_is_any_progress ()
794 {
795         [ `cat "${DBDIR}/new_success_in_current_run" 2> /dev/null | wc -l` -gt 0 ]
796 }
797
798 # ============= Get the all initial origins, separated by line feed =============
799 database_query_initial_orgins ()
800 {
801         local origin origin_init
802         origin=$1
803         if [ -e "${DBDIR}/moved_from/$origin/old_origs" ]
804         then
805                 for origin_init in `cat "${DBDIR}/moved_from/$origin/old_origs"`
806                 do
807                         [ -e "${DBDIR}/initial/$origin_init/installed_version" ] && echo "$origin_init"
808                 done
809         else
810                 [ -e "${DBDIR}/initial/$origin/installed_version" ] && echo "$origin"
811         fi
812         :
813 }