Closer to what will be the final version Index: Makefile =================================================================== RCS file: /cvs/ports/databases/sqlports/Makefile,v retrieving revision 1.10 diff -u -p -r1.10 Makefile --- Makefile 15 Sep 2007 22:27:39 -0000 1.10 +++ Makefile 18 Aug 2008 11:25:55 -0000 @@ -1,28 +1,35 @@ # $OpenBSD: Makefile,v 1.10 2007/09/15 22:27:39 simon Exp $ -CATEGORIES= databases -DISTNAME= sqlports-0.5 -PKGNAME= ${DISTNAME}p0 -DISTFILES= -COMMENT= sqlite database of ports -MAINTAINER= Marc Espie <[EMAIL PROTECTED]> - -PERMIT_PACKAGE_CDROM= Yes -PERMIT_PACKAGE_FTP= Yes -PERMIT_DISTFILES_CDROM= Yes -PERMIT_DISTFILES_FTP= Yes +CATEGORIES = databases +V = 1.0 +DISTNAME = sqlports-$V +DISTFILES = +COMMENT = sqlite database of ports +COMMENT-main = ${COMMENT}, user version +COMMENT-compact = ${COMMENT}, program version +MAINTAINER = Marc Espie <[EMAIL PROTECTED]> +FULLPKGNAME-compact = sqlports-compact-$V +FULLPKGNAME-main = sqlports-$V -DBNAME= ${WRKBUILD}/sqlports + +PERMIT_PACKAGE_CDROM = Yes +PERMIT_PACKAGE_FTP = Yes +PERMIT_DISTFILES_CDROM =Yes +PERMIT_DISTFILES_FTP = Yes +MULTI_PACKAGES = -main -compact + +DBNAME = ${WRKBUILD}/sqlports do-build: - cd ${PORTSDIR} && ${MAKE} dump-vars| \ + cd ${PORTSDIR} && ${MAKE} dump-vars NO_IGNORE=Yes| \ perl ${FILESDIR}/mksqlitedb ${DBNAME} do-install: ${INSTALL_DATA} ${DBNAME} ${PREFIX}/share + ${INSTALL_DATA} ${DBNAME}-compact ${PREFIX}/share -BUILD_DEPENDS= ::databases/p5-DBD-SQLite -NO_REGRESS= Yes -NO_CHECKSUM= Yes +BUILD_DEPENDS = ::databases/p5-DBD-SQLite +NO_REGRESS = Yes +NO_CHECKSUM = Yes .include <bsd.port.mk> Index: files/mksqlitedb =================================================================== RCS file: /cvs/ports/databases/sqlports/files/mksqlitedb,v retrieving revision 1.4 diff -u -p -r1.4 mksqlitedb --- files/mksqlitedb 27 Dec 2006 11:16:10 -0000 1.4 +++ files/mksqlitedb 18 Aug 2008 11:25:55 -0000 @@ -22,6 +22,9 @@ use strict; use warnings; +use Getopt::Std; + +our ($opt_v); sub words($) { @@ -31,6 +34,262 @@ sub words($) return split(/\s+/, $v); } +package AbstractInserter; +# this is the object to use to put stuff into the db... +sub new +{ + my ($class, $db, $i) = @_; + bless {db => $db, transaction => 0, threshold => $i, vars => {}, done => {} }, $class; +} + +sub set +{ + my ($self, $ref) = @_; + $self->{ref} = $ref; +} + +sub db +{ + return shift->{db}; +} + +sub last_id +{ + return shift->db->func('last_insert_rowid'); +} + +sub insert_done +{ + my $self = shift; + if ($self->{transaction}++ % $self->{threshold} == 0) { + $self->db->commit; + } +} + +sub new_table +{ + my ($self, $name, @cols) = @_; + + return if defined $self->{done}->{$name}; + + $self->db->do("DROP TABLE IF EXISTS $name"); + print "CREATE TABLE $name (".join(', ', @cols).")\n" if $main::opt_v; + $self->db->do("CREATE TABLE $name (".join(', ', @cols).")"); + $self->{done}->{$name} = 1; +} + +sub prepare +{ + my ($self, $s) = @_; + return $self->db->prepare($s); +} + +sub finish_port +{ + my $self = shift; + my @values = ($self->ref); + for my $i (@{$self->{varlist}}) { + push(@values, $self->{vars}->{$i}); + } + $self->{insert_ports}->execute(@values); + $self->{vars} = {}; +} + +sub addports +{ + my ($self, $var, $value) = @_; + $self->{vars}->{$var} = $value; +} + +sub create_tables +{ + my ($self, $vars) = @_; + + $self->db->commit; + $self->new_table("Ports", $self->pathref." PRIMARY KEY", map {$_." ".$vars->{$_}->sqltype } sort @{$self->{varlist}}); + $self->{insert_ports} = $self->prepare("INSERT OR REPLACE INTO Ports (". + join(", ", "FULLPKGPATH", @{$self->{varlist}}).") VALUES (". + join(", ", "?", map {'?'} @{$self->{varlist}}).")"); + $self->{insert_pathkey} = $self->prepare("INSERT OR REPLACE INTO Paths (FULLPKGPATH, PKGPATH) VALUES (?, ?)"); +} + +sub ref +{ + return shift->{ref}; +} + +package CompactInserter; +our @ISA=(qw(AbstractInserter)); + +our $c = { + Library => 0, + Run => 1, + Build => 2, + Regress => 3 +}; + +sub convert_depends +{ + my ($self, $value) = @_; + return $c->{$value}; +} + + +sub pathref +{ + return "FULLPKGPATH INTEGER NOT NULL"; +} + +sub create_tables +{ + my ($self, $vars) = @_; + # create the various tables, dropping old versions + + my @keys; + + while (my ($name, $class) = each %$vars) { + if (!defined( $class->table() )) { + push(@keys, $name." ".$class->sqltype); + push(@{$self->{varlist}}, $name); + } + $class->create_table($self); + } + + $self->new_table("Paths", "ID INTEGER PRIMARY KEY", "FULLPKGPATH TEXT NOT NULL UNIQUE", "PKGPATH INTEGER"); + $self->SUPER::create_tables($vars); + $self->{find_pathkey} = $self->prepare("SELECT ID From Paths WHERE FULLPKGPATH=(?)"); + $self->SUPER::create_tables($vars); +} + +sub find_pathkey +{ + my ($self, $key) = @_; + + if ($key eq '') { + print STDERR "Empty pathkey\n"; + return 0; + } + + # get pathkey for existing value + $self->{find_pathkey}->execute($key); + my $z = $self->{find_pathkey}->fetchrow_arrayref; + if (!defined $z) { + # if none, we create one + my $path = $key; + $path =~ s/\,.*//; + if ($path ne $key) { + $path = $self->find_pathkey($path); + } else { + $path = undef; + } + $self->{insert_pathkey}->execute($key, $path); + $self->insert_done; + return $self->last_id; + } else { + return $z->[0]; + } +} + +sub set_newkey +{ + my ($self, $key) = @_; + + $self->set($self->find_pathkey($key)); +} + +sub find_keyword_id +{ + my ($self, $key, $t) = @_; + $self->{$t}->{find_key1}->execute($key); + my $a = $self->{$t}->{find_key1}->fetchrow_arrayref; + if (!defined $a) { + $self->{$t}->{find_key2}->execute($key); + $self->insert_done; + return $self->last_id; + } else { + return $a->[0]; + } +} + +sub create_keyword_table +{ + my ($self, $t) = @_; + $self->new_table($t, + "KEYREF INTEGER PRIMARY KEY AUTOINCREMENT", + "VALUE TEXT NOT NULL UNIQUE"); + $self->{$t}->{find_key1} = $self->prepare("SELECT KEYREF FROM $t WHERE VALUE=(?)"); + $self->{$t}->{find_key2} = $self->prepare("INSERT INTO $t (VALUE) VALUES (?)"); +} + +package NormalInserter; +our @ISA=(qw(AbstractInserter)); + +our $c = { + Library => 'L', + Run => 'R', + Build => 'B', + Regress => 'Regress' +}; + +sub convert_depends +{ + my ($self, $value) = @_; + return $c->{$value}; +} + +sub create_tables +{ + my ($self, $vars) = @_; + # create the various tables, dropping old versions + + my @keys; + + while (my ($name, $class) = each %$vars) { + push(@keys, $name." ".$class->sqltype); + push(@{$self->{varlist}}, $name); + $class->create_table($self); + } + + $self->new_table("Paths", "FULLPKGPATH TEXT NOT NULL PRIMARY KEY", "PKGPATH TEXT NOT NULL"); + $self->SUPER::create_tables($vars); + +} + +sub pathref +{ + return "FULLPKGPATH TEXT NOT NULL"; +} + +sub set_newkey +{ + my ($self, $key) = @_; + + my $path = $key; + $path =~ s/\,.*//; + $self->{insert_pathkey}->execute($key, $path); + $self->set($key); + $self->insert_done; +} + +sub find_pathkey +{ + my ($self, $key) = @_; + + return $key; +} + +# no keyword for this dude +sub find_keyword_id +{ + my ($self, $key, $t) = @_; + return $key; +} + +sub create_keyword_table +{ + my ($self, $t) = @_; +} + # use a Template Method approach to store the variable values. # rule: we store each value in the main table, after converting YesNo @@ -38,11 +297,92 @@ sub words($) # to store them in secondary tables (because of one/many associations). package AnyVar; +sub new +{ + my ($class, $var, $value) = @_; + bless [$var, $value], $class; +} + +sub var +{ + return shift->[0]; +} + +sub value +{ + return shift->[1]; +} + +sub add +{ + my ($self, $ins) = @_; + $ins->addports($self->var, $self->value); +} + +sub addvalue +{ + my ($self, $ins, $value) = @_; + $ins->addports($self->var, $value); +} + +sub sqltype() +{ + return "TEXT"; +} + +sub table() +{ + return undef; +} + +sub keyword +{ + my ($self, $ins, $value) = @_; + return $ins->find_keyword_id($value, $self->keyword_table); +} + +# by default, there's no separate table +sub create_table +{ +} + +sub keyword_table() +{ + return "Keywords"; +} + +package KeyVar; +our @ISA=(qw(AnyVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - my $stmt=$db->prepare("UPDATE Ports SET $var=(?) WHERE RowID=(?)"); - $stmt->execute($value, $rowid); + my ($self, $ins) = @_; + $self->SUPER::addvalue($ins, $self->keyword($ins, $self->value)); +} + +sub sqltype() +{ + return "INTEGER NOT NULL"; +} + +sub create_table +{ + my ($self, $inserter) = @_; + $inserter->create_keyword_table($self->keyword_table); +} + +package OptKeyVar; +our @ISA=(qw(KeyVar)); +sub add +{ + my ($self, $ins) = @_; + if ($self->value ne '') { + $self->SUPER::add($ins); + } +} + +sub sqltype() +{ + return "INTEGER"; } package YesNoVar; @@ -50,8 +390,13 @@ our @ISA=(qw(AnyVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - $class->SUPER::add($pkgpath, $db, $var, $value =~ m/^Yes/i ? 1 : undef, $rowid); + my ($self, $ins) = @_; + $self->SUPER::addvalue($ins, $self->value =~ m/^Yes/i ? 1 : undef); +} + +sub sqltype() +{ + return "INTEGER"; } # variable is always defined, but we don't need to store empty values. @@ -60,9 +405,9 @@ our @ISA=(qw(AnyVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - return if $value eq ''; - $class->SUPER::add($pkgpath, $db, $var, $value, $rowid); + my ($self, $ins) = @_; + return if $self->value eq ''; + $self->SUPER::add($ins); } @@ -70,55 +415,124 @@ sub add # end up being treated as WANTLIB as well. package DependsVar; +our @ISA=(qw(AnyVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - AnyVar->add($pkgpath, $db, $var, $value, $rowid); - for my $depends (main::words $value) { + my ($self, $ins) = @_; + $self->SUPER::add($ins); + for my $depends (main::words $self->value) { my ($libs, $pkgspec, $pkgpath2, $rest) = split(/\:/, $depends); - my $stmt = $db->prepare("INSERT INTO Depends (FULLPKGPATH, FULLDEPENDS, DEPENDSPATH, TYPE) VALUES (?, ?, ?, ?)"); - $stmt->execute($pkgpath, $depends, $pkgpath2, $class->type()); + my $stmt = $ins->prepare("INSERT OR REPLACE INTO Depends (FULLPKGPATH, FULLDEPENDS, DEPENDSPATH, TYPE, PKGSPEC, REST) VALUES (?, ?, ?, ?, ?, ?)"); + $stmt->execute($ins->ref, $depends, $ins->find_pathkey($pkgpath2), $ins->convert_depends($self->depends_type), $pkgspec, $rest); + $ins->insert_done; if ($libs ne '') { for my $lib (split(/\,/, $libs)) { - $class->addlib($pkgpath, $db, $lib); + $self->addlib($ins, $lib); } } } } +sub create_table +{ + my ($self, $inserter) = @_; + $inserter->new_table("Depends", $inserter->pathref, "FULLDEPENDS TEXT NOT NULL", "PKGSPEC TEXT" , "REST TEXT", "DEPENDSPATH TEXT NOT NULL", "TYPE TEXT NOT NULL"); +} + sub addlib { } +sub table() +{ + return "Depends"; +} + +sub sqltype() +{ + return "TEXT"; +} + package LibDependsVar; our @ISA=(qw(DependsVar)); -sub type() { 'L' } +sub depends_type() { 'Library' } sub addlib { - my ($class, $pkgpath, $db, $lib) = @_; - WantlibVar->addvalue($pkgpath, $db, $lib); + my ($self, $ins, $lib) = @_; + WantlibVar->addvalue($ins, $lib); } package RunDependsVar; our @ISA=(qw(DependsVar)); -sub type() { 'R' } +sub depends_type() { 'Run' } package BuildDependsVar; our @ISA=(qw(DependsVar)); -sub type() { 'B' } +sub depends_type() { 'Build' } package RegressDependsVar; our @ISA=(qw(DependsVar)); -sub type() { 'Regress' } +sub depends_type() { 'Regress' } -# Stuff that gets stored in another table as well +# Stuff that gets stored in another table package SecondaryVar; +our @ISA=(qw(AnyVar)); sub addvalue { - my ($class, $pkgpath, $db, $value) = @_; - my $stmt = $db->prepare("INSERT OR REPLACE INTO ".$class->table." (FULLPKGPATH, VALUE) VALUES (?, ?)"); - $stmt->execute($pkgpath, $value); + my ($self, $ins, $value) = @_; + my $stmt = $ins->prepare("INSERT OR REPLACE INTO ".$self->table." (FULLPKGPATH, VALUE) VALUES (?, ?)"); + $stmt->execute($ins->ref, $value); + $ins->insert_done; +} + +sub addkeyword +{ + my ($self, $ins, $value) = @_; + $self->addvalue($ins, $self->keyword($ins, $value)); +} + +sub create_table +{ + my ($self, $inserter) = @_; + $inserter->new_table($self->table, $inserter->pathref, + "VALUE TEXT NOT NULL", "UNIQUE(FULLPKGPATH, VALUE)"); + KeyVar::create_table($self, $inserter); +} + +sub keyword_table() +{ + return "Keywords"; +} +sub sqltype() { "TEXT" } + +package MasterSitesVar; +our @ISA=(qw(AnyVar)); +sub add +{ + my ($self, $ins) = @_; + + my $stmt = $ins->prepare("INSERT OR REPLACE INTO ".$self->table." (FULLPKGPATH, N, VALUE) VALUES (?, ?, ?)"); + + my $n; + if ($self->var =~ m/^MASTER_SITES(\d)$/) { + $n = $1; + } + $stmt->execute($ins->ref, $n, $self->value); + $ins->insert_done; +} + +sub create_table +{ + my ($self, $inserter) = @_; + $inserter->new_table($self->table, $inserter->pathref, + "N INTEGER", "VALUE TEXT NOT NULL", "UNIQUE(FULLPKGPATH, N, VALUE)"); + KeyVar::create_table($self, $inserter); +} + +sub table() +{ + return "MasterSites"; } # Generic handling for any blank-separated list @@ -127,10 +541,22 @@ our @ISA=(qw(SecondaryVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - AnyVar->add($pkgpath, $db, $var, $value, $rowid); - for my $d (main::words $value) { - $class->addvalue($pkgpath, $db, $d) if $d ne ''; + my ($self, $ins) = @_; + $self->SUPER::add($ins); + for my $d (main::words $self->value) { + $self->addvalue($ins, $d) if $d ne ''; + } +} + +package ListKeyVar; +our @ISA=(qw(SecondaryVar)); + +sub add +{ + my ($self, $ins) = @_; + $self->SUPER::add($ins); + for my $d (main::words $self->value) { + $self->addkeyword($ins, $d) if $d ne ''; } } @@ -139,9 +565,9 @@ our @ISA=(qw(SecondaryVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - AnyVar->add($pkgpath, $db, $var, $value, $rowid); - my @l = (main::words $value); + my ($self, $ins) = @_; + $self->SUPER::add($ins); + my @l = (main::words $self->value); while (my $v = shift @l) { while ($v =~ m/^[^']*\'[^']*$/ || $v =~m/^[^"]*\"[^"]*$/) { $v.=' '.shift @l; @@ -152,38 +578,52 @@ sub add if ($v =~ m/^\'(.*)\'$/) { $v = $1; } - $class->addvalue($pkgpath, $db, $v) if $v ne ''; + $self->addvalue($ins, $v) if $v ne ''; } } -package DefinedListVar; -our @ISA=(qw(ListVar)); +package DefinedListKeyVar; +our @ISA=(qw(ListKeyVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - return if $value eq ''; - $class->SUPER::add($pkgpath, $db, $var, $value, $rowid); + my ($self, $ins) = @_; + return if $self->value eq ''; + $self->SUPER::add($ins); } package FlavorsVar; -our @ISA=(qw(DefinedListVar)); +our @ISA=(qw(DefinedListKeyVar)); sub table() { 'Flavors' } +package PseudoFlavorsVar; +our @ISA=(qw(DefinedListKeyVar)); +sub table() { 'PseudoFlavors' } + package CategoriesVar; -our @ISA=(qw(ListVar)); +our @ISA=(qw(ListKeyVar)); sub table() { 'Categories' } +sub keyword_table() { 'CategoryKeys' } package MultiVar; our @ISA=(qw(ListVar)); sub table() { 'Multi' } +sub add +{ + my ($self, $ins) = @_; + return if $self->value eq '-'; + $self->SUPER::add($ins); +} + package ModulesVar; -our @ISA=(qw(ListVar)); +our @ISA=(qw(ListKeyVar)); sub table() { 'Modules' } +sub keyword_table() { 'ModuleKeys' } package ConfigureVar; -our @ISA=(qw(DefinedListVar)); +our @ISA=(qw(DefinedListKeyVar)); sub table() { 'Configure' } +sub keyword_table() { 'ConfigureKeys' } package ConfigureArgsVar; our @ISA=(qw(QuotedListVar)); @@ -192,27 +632,52 @@ sub table() { 'ConfigureArgs' } package WantlibVar; our @ISA=(qw(ListVar)); sub table() { 'Wantlib' } +sub _add +{ + my ($self, $ins, $value, $extra) = @_; + my $stmt = $ins->prepare("INSERT OR REPLACE INTO ".$self->table." (FULLPKGPATH, VALUE, EXTRA) VALUES (?, ?, ?)"); + $stmt->execute($ins->ref, + $self->keyword($ins, $value), $extra); + $ins->insert_done; +} + sub addvalue { - my ($class, $pkgpath, $db, $value) = @_; - $class->SUPER::addvalue($pkgpath, $db, $value); - if ($value =~ m/\.(?:\>?\=)?\d+\.\d+$/) { - $class->SUPER::addvalue($pkgpath, $db, $`); - } elsif ($value =~ m/\.(?:\>?\=)?\d+$/) { - $class->SUPER::addvalue($pkgpath, $db, $`); + my ($self, $ins, $value) = @_; + if ($value =~ m/^(.*)(\.(?:\>?\=)?\d+\.\d+)$/) { + $self->_add($ins, $1, $2); + } elsif ($value =~ m/^(.*)(\.(?:\>?\=)?\d+)$/) { + $self->_add($ins, $1, $2); + } else { + $self->_add($ins, $value, undef); } } +sub create_table +{ + my ($self, $inserter) = @_; + $inserter->new_table($self->table, $inserter->pathref, + "VALUE TEXT NOT NULL", "EXTRA TEXT", "UNIQUE(FULLPKGPATH, VALUE)"); + KeyVar::create_table($self, $inserter); +} + +sub keyword_table() { 'Library' } + +package OnlyForArchVar; +our @ISA=(qw(QuotedListKeyVar)); +sub table() { 'OnlyForArch' } +sub keyword_table() { 'Arches' } + package FileVar; our @ISA=(qw(SecondaryVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - AnyVar->add($pkgpath, $db, $var, $value, $rowid); - open my $file, '<', $value or return; + my ($self, $ins) = @_; + $self->SUPER::add($ins); + open my $file, '<', $self->value or return; local $/ = undef; - $class->addvalue($pkgpath, $db, <$file>); + $self->addvalue($ins, <$file>); } sub table() { 'Descr' } @@ -222,31 +687,79 @@ our @ISA=(qw(AnyVar)); sub add { - my ($class, $pkgpath, $db, $var, $value, $rowid) = @_; - $class->SUPER::add($pkgpath, $db, $var, $value, $rowid); - my $stmt = $db->prepare("INSERT INTO Shared_Libs (FULLPKGPATH, LIBNAME, VERSION) VALUES (?, ?, ?)"); - my %t = main::words($value); + my ($self, $ins) = @_; + $self->SUPER::add($ins); + my $stmt = $ins->prepare("INSERT OR REPLACE INTO Shared_Libs (FULLPKGPATH, LIBNAME, VERSION) VALUES (?, ?, ?)"); + my %t = main::words($self->value); while (my ($k, $v) = each %t) { - $stmt->execute($pkgpath, $k, $v); + $stmt->execute($ins->ref, $self->keyword($ins, $k), $v); + $ins->insert_done; } } +sub create_table +{ + my ($self, $inserter) = @_; + $inserter->new_table("Shared_Libs", $inserter->pathref, + "LIBNAME TEXT NOT NULL", "VERSION TEXT NOT NULL", + "UNIQUE (FULLPKGPATH, LIBNAME)"); + KeyVar::create_table($self, $inserter); +} + +sub table() +{ + "Shared_Libs" +} + +sub keyword_table() +{ + return "Library"; +} + +package EmailVar; +our @ISA=(qw(KeyVar)); +sub keyword_table() +{ + return "Email"; +} + +package YesKeyVar; +our @ISA=(qw(KeyVar)); +sub keyword_table() +{ + return "Keywords2"; +} + +package AutoVersionVar; +our @ISA=(qw(OptKeyVar)); + +sub keyword_table() +{ + return "AutoVersion"; +} package main; use DBI; +getopt('v'); my $dbname; if (@ARGV > 0) { $dbname = shift; } else { $dbname = 'sqlports'; } +my @inserters; my $db =DBI->connect("dbi:SQLite:dbname=$dbname", '', '', {AutoCommit => 0}); +my $db2 =DBI->connect("dbi:SQLite:dbname=$dbname-compact", '', '', {AutoCommit => 0}); +push(@inserters, NormalInserter->new($db, 1000)); +push(@inserters, CompactInserter->new($db2, 1000)); + + my $vars = { - AUTOCONF_VERSION => 'AnyVar', - AUTOMAKE_VERSION => 'AnyVar', + AUTOCONF_VERSION => 'AutoVersionVar', + AUTOMAKE_VERSION => 'AutoVersionVar', BROKEN => 'AnyVar', BUILD_DEPENDS => 'BuildDependsVar', CATEGORIES=> 'CategoriesVar', @@ -263,35 +776,35 @@ my $vars = { HOMEPAGE => 'AnyVar', IS_INTERACTIVE => 'AnyVar', LIB_DEPENDS => 'LibDependsVar', - MAINTAINER=> 'AnyVar', - MASTER_SITES => 'AnyVar', - MASTER_SITES0 => 'AnyVar', - MASTER_SITES1 => 'AnyVar', - MASTER_SITES2 => 'AnyVar', - MASTER_SITES3 => 'AnyVar', - MASTER_SITES4=> 'AnyVar', - MASTER_SITES5 => 'AnyVar', - MASTER_SITES6 => 'AnyVar', - MASTER_SITES7 => 'AnyVar', - MASTER_SITES8 => 'AnyVar', - MASTER_SITES9=> 'AnyVar', + 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', ONLY_FOR_ARCHS => 'AnyVar', PACKAGES => 'AnyVar', - PERMIT_DISTFILES_CDROM => 'AnyVar', - PERMIT_DISTFILES_FTP=> 'AnyVar', - PERMIT_PACKAGE_CDROM => 'AnyVar', - PERMIT_PACKAGE_FTP=> 'AnyVar', + PERMIT_DISTFILES_CDROM => 'YesKeyVar', + PERMIT_DISTFILES_FTP=> 'YesKeyVar', + PERMIT_PACKAGE_CDROM => 'YesKeyVar', + PERMIT_PACKAGE_FTP=> 'YesKeyVar', PKGNAME => 'AnyVar', - PKG_ARCH => 'AnyVar', - PSEUDO_FLAVORS => 'DefinedVar', + PKG_ARCH => 'KeyVar', + PSEUDO_FLAVORS => 'PseudoFlavorsVar', REGRESS_DEPENDS => 'RegressDependsVar', REGRESS_IS_INTERACTIVE => 'AnyVar', RUN_DEPENDS => 'RunDependsVar', - SEPARATE_BUILD => 'AnyVar', + SEPARATE_BUILD => 'YesKeyVar', SHARED_LIBS => 'SharedLibsVar', SHARED_ONLY => 'YesNoVar', SUBPACKAGE => 'DefinedVar', @@ -303,37 +816,16 @@ my $vars = { WANTLIB => 'WantlibVar', }; -# create the various tables, dropping old versions - -for my $t (qw(Categories Flavors Multi Modules Configure ConfigureArgs Wantlib)) { - $db->do("DROP TABLE IF EXISTS $t"); - $db->do("CREATE TABLE $t (FULLPKGPATH TEXT NOT NULL, VALUE TEXT NOT NULL, UNIQUE(FULLPKGPATH, VALUE))"); -} -$db->do("DROP TABLE IF EXISTS Depends"); -$db->do("CREATE TABLE Depends (FULLPKGPATH TEXT NOT NULL, FULLDEPENDS TEXT NOT NULL, DEPENDSPATH TEXT NOT NULL, TYPE TEXT NOT NULL)"); -$db->do("DROP TABLE IF EXISTS Shared_Libs"); -$db->do("CREATE TABLE Shared_Libs (FULLPKGPATH TEXT NOT NULL, LIBNAME TEXT NOT NULL, VERSION TEXT NOT NULL, UNIQUE (FULLPKGPATH, LIBNAME))"); -$db->do("DROP TABLE IF EXISTS Ports"); -$db->do("CREATE TABLE Ports (FULLPKGPATH TEXT NOT NULL PRIMARY KEY, ". - join(',', (map {$_." TEXT"} (keys %$vars))).")"); -$db->do("DROP TABLE IF EXISTS Paths"); -$db->do("CREATE TABLE Paths (FULLPKGPATH TEXT NOT NULL PRIMARY KEY, PKGPATH TEXT NOT NULL)"); -$db->do("DROP TABLE IF EXISTS Descr"); -$db->do("CREATE TABLE Descr (FULLPKGPATH TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL)"); -$db->commit(); - -my $stmt = $db->prepare("SELECT RowID FROM Ports WHERE FULLPKGPATH=(?)"); -my $stmt2= $db->prepare("INSERT INTO Ports (FULLPKGPATH) VALUES (?)"); -my $stmt3= $db->prepare("INSERT INTO Paths (FULLPKGPATH, PKGPATH) VALUES (?, ?)"); +for my $inserter (@inserters) { + $inserter->create_tables($vars); +} -my $i = 0; -my $rowid; my $lastkey; while (<STDIN>) { chomp; # kill noise if (m/^\=\=\=/) { - print $_, "\n"; + print "---", $_, "\n"; next; } next unless m/^(.*?)\.([A-Z][A-Z_0-9]*)\=(.*)$/; @@ -345,28 +837,23 @@ while (<STDIN>) { } if (!(defined $lastkey) || $key ne $lastkey) { - # get rowid for existing value - $stmt->execute($key); - my $z = $stmt->fetchall_arrayref; - if (@$z == 0) { - # if none, we create one - $stmt2->execute($key); - my $path = $key; - $path =~ s/\,.*//; - $stmt3->execute($key, $path); - $stmt->execute($key); - $z = $stmt->fetchall_arrayref; + if (defined $lastkey) { + for my $inserter (@inserters) { + $inserter->finish_port; + } + } + for my $inserter (@inserters) { + $inserter->set_newkey($key); } - $rowid = $z->[0]->[0]; $lastkey = $key; } - $vars->{$var}->add($key, $db, $var, $value, $rowid); - - # and we commit just once every 1000 transactions, for efficiency - $i++; - if ($i % 1000 == 0) { - $db->commit(); + my $v = $vars->{$var}->new($var, $value); + for my $inserter (@inserters) { + $v->add($inserter); } } -$db->commit(); +for my $inserter (@inserters) { + $inserter->finish_port; + $inserter->db->commit; +} Index: pkg/DESCR =================================================================== RCS file: pkg/DESCR diff -N pkg/DESCR --- pkg/DESCR 1 Aug 2006 16:22:22 -0000 1.4 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,74 +0,0 @@ -SQLite database of every port in the system. This can be queried through -e.g., sqlitebrowser, or any kind of programming interface. - -Database Schema: -- Ports(FULLPKGPATH, ...) -holds all the information retrieved through various variables, e.g.,: - AUTOCONF_VERSION - AUTOMAKE_VERSION - BROKEN - *DEPENDS - CATEGORIES - COMMENT - CONFIGURE_STYLE - DESCR - PACKAGING - DISTFILES - DISTNAME - DIST_SUBDIR - FLAVORS - HOMEPAGE - IS_INTERACTIVE - MAINTAINER - MASTER_SITES* - MODULES - MULTI_PACKAGES - NO_* - ONLY_FOR_ARCHS - PACKAGES - PERMIT_* - PKGNAME - PKG_ARCH - PSEUDO_FLAVORS - REGRESS_IS_INTERACTIVE - RUN_DEPENDS - SEPARATE_BUILD - SHARED_LIBS - SHARED_ONLY - SUBPACKAGE - SUPDISTFILES - USE_* - WANTLIB -This information is mostly unchanged, except for replacing Yes/No variables -with 1/0. Variables not present in a given port are left undefined. - -The FULLPKGPATH is complete, including flavors markers. For each port with -MULTI_PACKAGES setting, another entry is written with PACKAGING set, and -the correct SUBPACKAGE. - -- Paths (FULLPKGPATH, PKGPATH) -PKGPATH is the stripped down version or FULLPKGPATH, without flavors -or subpackage markers. - -- Flavors(FULLPKGPATH, VALUE) -- Categories(FULLPKGPATH, VALUE) -- Multi(FULLPKGPATH, VALUE) -- Modules(FULLPKGPATH, VALUE) -- Configure(FULLPKGPATH, VALUE) -- ConfigureArgs(FULLPKGPATH, VALUE) -All of these values are actually lists. After disassembling the list, -one can find many entries in these secondary tables. - -- Depends(FULLPKGPATH, FULLDEPENDS, DEPENDSPATH, TYPE) -All depends are stored in a single table, including the type: -R -> run -L -> lib -B -> build -Regress -> regress -with FULLDEPENDS the full text of the dependency, and DEPENDSPATH the PKGPATH -we depend upon. -- Wantlib(FULLPKGPATH, VALUE) -All the libraries the FULLPKGPATH depends upon, with and without version number, -coming from either the WANTLIB variable or various LIB_DEPENDS. - -- Shared_Libs(FULLPKGPATH, LIBNAME, VERSION) Index: pkg/DESCR-compact =================================================================== RCS file: pkg/DESCR-compact diff -N pkg/DESCR-compact --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ pkg/DESCR-compact 18 Aug 2008 11:25:55 -0000 @@ -0,0 +1,91 @@ +SQLite database of every port in the system. This can be queried through +e.g., sqlitebrowser, or any kind of programming interface. + +This schema is mostly optimized for tools, and cumbersome to query by +hand. + +Database Schema: +- Paths (ID, FULLPKGPATH, PKGPATH) +PKGPATH points to a PATHS entry corresponding to the stripped down version of +FULLPKGPATH, without flavors or subpackage markers, or is null if FULLPKGPATH +is already stripped. Every other FULLPKGPATH, PKGPATH, DEPENDSPATH entry +in the database points to this table. + +- Ports(FULLPKGPATH, ...) +holds all the information retrieved through various variables that is not +stored in specialized tables, e.g.,: + AUTOCONF_VERSION + AUTOMAKE_VERSION + BROKEN + COMMENT + DESCR + PACKAGING + DISTFILES + DISTNAME + DIST_SUBDIR + FLAVORS + HOMEPAGE + IS_INTERACTIVE + MAINTAINER + MULTI_PACKAGES + NO_* + ONLY_FOR_ARCHS + PACKAGES + PERMIT_* + PKGNAME + PKG_ARCH + PSEUDO_FLAVORS + REGRESS_IS_INTERACTIVE + SEPARATE_BUILD + SHARED_ONLY + SUBPACKAGE + SUPDISTFILES + USE_* + +This information is mostly unchanged, except for replacing Yes/No variables +with 1/0. Variables not present in a given port are left undefined. + +The FULLPKGPATH is complete, including flavors markers. For each port with +MULTI_PACKAGES setting, another entry is written with PACKAGING set, and +the correct SUBPACKAGE. + +- Flavors(FULLPKGPATH, VALUE) +- PseudoFlavors(FULLPKGPATH, VALUE) +- Categories(FULLPKGPATH, VALUE) +- Multi(FULLPKGPATH, VALUE) ('-' values are not stored) +- Modules(FULLPKGPATH, VALUE) +- Configure(FULLPKGPATH, VALUE) (corresponds to CONFIGURE_STYLE) +- ConfigureArgs(FULLPKGPATH, VALUE) +- MasterSites(FULLPKGPATH, N, VALUE) +All of these values are actually lists. After disassembling the list, +one can find many entries in these secondary tables. + + +Each keyword table follows the same scheme +TABLENAME(KEYREF, VALUE) + + +- Depends(FULLPKGPATH, FULLDEPENDS, PKGSPEC, REST, DEPENDSPATH, TYPE) +All depends are stored in a single table, including the type: +0 -> library +1 -> run +2 -> build +3 -> regress +with FULLDEPENDS the full text of the dependency, and DEPENDSPATH the key to +the PKGPATH we depend upon. +- Wantlib(FULLPKGPATH, VALUE, EXTRA) +All the libraries the FULLPKGPATH depends upon, with and without version number, +coming from either the WANTLIB variable or various LIB_DEPENDS. + +- Shared_Libs(FULLPKGPATH, LIBNAME, VERSION) + +Some information, both in the main table and in secondary tables +is stored as keyword references to other tables: +AUTOCONF_VERSION, AUTOMAKE_VERSION -> AUTOVERSION +MAINTAINER -> EMAIL +CATEGORIES -> CATEGORYKEYS +CONFIGURE -> CONFIGURE_KEYS +MODULES -> MODULEKEYS +WANTLIB.VALUE, SHARED_LIBS.LIBNAME -> LIBRARY +PERMIT_*, SEPARATE_BUILD -> KEYWORDS2 +FLAVORS, PSEUDO_FLAVORS, PKG_ARCH -> KEYWORDS Index: pkg/DESCR-main =================================================================== RCS file: pkg/DESCR-main diff -N pkg/DESCR-main --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ pkg/DESCR-main 18 Aug 2008 11:25:55 -0000 @@ -0,0 +1,74 @@ +SQLite database of every port in the system. This can be queried through +e.g., sqlitebrowser, or any kind of programming interface. + +Database Schema: +- Ports(FULLPKGPATH, ...) +holds all the information retrieved through various variables, e.g.,: + AUTOCONF_VERSION + AUTOMAKE_VERSION + BROKEN + *DEPENDS + CATEGORIES + COMMENT + CONFIGURE_STYLE + DESCR + PACKAGING + DISTFILES + DISTNAME + DIST_SUBDIR + FLAVORS + HOMEPAGE + IS_INTERACTIVE + MAINTAINER + MASTER_SITES* + MODULES + MULTI_PACKAGES + NO_* + ONLY_FOR_ARCHS + PACKAGES + PERMIT_* + PKGNAME + PKG_ARCH + PSEUDO_FLAVORS + REGRESS_IS_INTERACTIVE + RUN_DEPENDS + SEPARATE_BUILD + SHARED_LIBS + SHARED_ONLY + SUBPACKAGE + SUPDISTFILES + USE_* + WANTLIB +This information is mostly unchanged, except for replacing Yes/No variables +with 1/0. Variables not present in a given port are left undefined. + +The FULLPKGPATH is complete, including flavors markers. For each port with +MULTI_PACKAGES setting, another entry is written with PACKAGING set, and +the correct SUBPACKAGE. + +- Paths (FULLPKGPATH, PKGPATH) +PKGPATH is the stripped down version or FULLPKGPATH, without flavors +or subpackage markers. + +- Flavors(FULLPKGPATH, VALUE) +- Categories(FULLPKGPATH, VALUE) +- Multi(FULLPKGPATH, VALUE) +- Modules(FULLPKGPATH, VALUE) +- Configure(FULLPKGPATH, VALUE) +- ConfigureArgs(FULLPKGPATH, VALUE) +All of these values are actually lists. After disassembling the list, +one can find many entries in these secondary tables. + +- Depends(FULLPKGPATH, FULLDEPENDS, DEPENDSPATH, TYPE) +All depends are stored in a single table, including the type: +R -> run +L -> lib +B -> build +Regress -> regress +with FULLDEPENDS the full text of the dependency, and DEPENDSPATH the PKGPATH +we depend upon. +- Wantlib(FULLPKGPATH, VALUE) +All the libraries the FULLPKGPATH depends upon, with and without version number, +coming from either the WANTLIB variable or various LIB_DEPENDS. + +- Shared_Libs(FULLPKGPATH, LIBNAME, VERSION) Index: pkg/PLIST =================================================================== RCS file: pkg/PLIST diff -N pkg/PLIST --- pkg/PLIST 10 Jul 2006 10:57:59 -0000 1.1.1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,2 +0,0 @@ [EMAIL PROTECTED] $OpenBSD: PLIST,v 1.1.1.1 2006/07/10 10:57:59 espie Exp $ -share/sqlports Index: pkg/PLIST-compact =================================================================== RCS file: pkg/PLIST-compact diff -N pkg/PLIST-compact --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ pkg/PLIST-compact 18 Aug 2008 11:25:55 -0000 @@ -0,0 +1,2 @@ [EMAIL PROTECTED] $OpenBSD: PLIST,v 1.1.1.1 2006/07/10 10:57:59 espie Exp $ +share/sqlports-compact Index: pkg/PLIST-main =================================================================== RCS file: pkg/PLIST-main diff -N pkg/PLIST-main --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ pkg/PLIST-main 18 Aug 2008 11:25:55 -0000 @@ -0,0 +1,2 @@ [EMAIL PROTECTED] $OpenBSD: PLIST,v 1.1.1.1 2006/07/10 10:57:59 espie Exp $ +share/sqlports