#! /usr/bin/perl # $OpenBSD: mksqlitedb,v 1.34 2011/09/24 07:37:34 espie Exp $ # # Copyright (c) 2006-2010 Marc Espie # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # example script that shows how to store all variable values into a # database, using SQLite for that purpose. # # usage: cd /usr/ports && make dump-vars |mksqlitedb use strict; use warnings; use FindBin; use lib $FindBin::Bin; use Getopt::Std; use Column; use Var; use Inserter; use DBI; our ($opt_v, $opt_q, $opt_p); sub parse_dump { my ($inserter, $vars, $fd, $unknown) = @_; my $lastkey; while (<$fd>) { chomp; # kill noise if (s/^\=\=\=/---/) { print $_, "\n"; next; } next unless m/^(.*?)\.([A-Z][A-Z_0-9]*)(?:\-([a-z0-9]+))?\=(.*)$/; my ($key, $var, $arch, $value) = ($1, $2, $3, $4); # strip extra quotes if ($value =~ m/^\"(.*)\"$/) { $value = $1; } if (!(defined $lastkey) || $key ne $lastkey) { if (defined $lastkey) { $inserter->finish_port; } $inserter->mark_done($key); if ($key =~ m/^(.*)\,\-main((?:\,.*)?)$/) { $inserter->mark_done("$1$2"); } $inserter->set_newkey($key); $lastkey = $key; } if (defined $vars->{$var}) { $inserter->add_var($vars->{$var}->new($var, $value, $arch)); } else { $unknown->{$var} //= $key; } } $inserter->finish_port; $inserter->commit_to_db; } sub dump_dirs { my ($inserter, $vars, $unknown, $todo) = @_; my ($pid, $fd); unless (defined($pid = open($fd, "-|"))) { die "can't fork : $!"; } if ($pid) { parse_dump($inserter, $vars, $fd, $unknown); close $fd || warn $!; } else { if (defined $todo) { $ENV{'SUBDIR'} = join(' ', keys %$todo); } if ($opt_p) { $ENV{'REPORT_PROBLEM_LOGFILE'}= $opt_p; } $ENV{'NO_IGNORE'} = 'Yes'; exec {'make'} ("make", "dump-vars"); die $!; } } getopts('vq:p:'); my $dbname; if (@ARGV > 0) { $dbname = shift; } else { $dbname = 'sqlports'; } my $inserter = InserterList->new; my $db = DBI->connect("dbi:SQLite:dbname=$dbname", '', '', {AutoCommit => 0}); my $db2 = DBI->connect("dbi:SQLite:dbname=$dbname-compact", '', '', {AutoCommit => 0}); my $normal = NormalInserter->new($db, 1000, $opt_v); $inserter->add($normal, CompactInserter->new($db2, 1000, $opt_v)); my $vars = { AUTOCONF_VERSION => 'AutoVersionVar', AUTOMAKE_VERSION => 'AutoVersionVar', BROKEN => 'BrokenVar', BUILD_DEPENDS => 'BuildDependsVar', CATEGORIES => 'CategoriesVar', COMES_WITH => 'DefinedVar', COMMENT => 'AnyVar', CONFIGURE_ARGS => 'ConfigureArgsVar', CONFIGURE_STYLE => 'ConfigureVar', DESCR => 'FileVar', DISTFILES => 'AnyVar', PATCHFILES => 'AnyVar', DISTNAME => 'AnyVar', DIST_SUBDIR => 'DefinedVar', EPOCH => 'AnyVar', FLAVORS => 'FlavorsVar', FULLPKGNAME => 'AnyVar', HOMEPAGE => 'AnyVar', IGNORE => 'DefinedVar', IS_INTERACTIVE => 'AnyVar', LIB_DEPENDS => 'LibDependsVar', MAINTAINER=> 'EmailVar', MASTER_SITES => 'MasterSitesVar', MASTER_SITES0 => 'MasterSitesVar', MASTER_SITES1 => 'MasterSitesVar', MASTER_SITES2 => 'MasterSitesVar', MASTER_SITES3 => 'MasterSitesVar', MASTER_SITES4=> 'MasterSitesVar', MASTER_SITES5 => 'MasterSitesVar', MASTER_SITES6 => 'MasterSitesVar', MASTER_SITES7 => 'MasterSitesVar', MASTER_SITES8 => 'MasterSitesVar', MASTER_SITES9=> 'MasterSitesVar', MODULES => 'ModulesVar', MULTI_PACKAGES => 'MultiVar', NO_BUILD => 'YesNoVar', NO_REGRESS => 'YesNoVar', NOT_FOR_ARCHS => 'NotForArchListVar', ONLY_FOR_ARCHS => 'OnlyForArchListVar', PERMIT_DISTFILES_CDROM => 'YesKeyVar', PERMIT_DISTFILES_FTP=> 'YesKeyVar', PERMIT_PACKAGE_CDROM => 'YesKeyVar', PERMIT_PACKAGE_FTP=> 'YesKeyVar', PKGNAME => 'AnyVar', PKGSPEC => 'AnyVar', PKG_ARCH => 'ArchKeyVar', PSEUDO_FLAVOR => 'AnyVar', PSEUDO_FLAVORS => 'PseudoFlavorsVar', REGRESS_DEPENDS => 'RegressDependsVar', REGRESS_IS_INTERACTIVE => 'AnyVar', REVISION => 'AnyVar', RUN_DEPENDS => 'RunDependsVar', SEPARATE_BUILD => 'YesKeyVar', SHARED_LIBS => 'SharedLibsVar', SHARED_ONLY => 'YesNoVar', SUBPACKAGE => 'DefinedVar', SUPDISTFILES => 'AnyVar', TARGETS => 'TargetsVar', USE_GMAKE => 'YesNoVar', USE_GROFF => 'YesNoVar', USE_LIBTOOL => 'YesNoGnuVar', WANTLIB => 'WantlibVar', }; $inserter->create_tables($vars); my $unknown = {}; dump_dirs($inserter, $vars, $unknown, undef); while (1) { my $todo = {}; my $stuff = 0; for my $v (keys %{$normal->{todo}}) { next if $normal->{done}{$v}; $todo->{$v} = 1; $stuff = 1; } last if !$stuff; $normal->{todo} = {}; print "Next pass\n"; dump_dirs($inserter, $vars, $unknown, $todo); for my $v (keys %$todo) { if (!$normal->{done}{$v}) { $normal->{done}{$v} = 1; } } } while (my ($k, $v) = each %$unknown) { next if $k eq 'CHECKSUM_FILE'; print STDERR "Unknown variable $k in $v\n"; } if (defined $opt_q) { open(my $log, ">", $opt_q) or die $!; $inserter->write_log($log); } else { $inserter->write_log(\*STDERR); }