Embedix-DB
view release on metacpan or search on metacpan
my %item;
my $s = 'insert into build_vars (node_id, name, value) values (?, ?, ?)';
my $sth = $dbh->prepare($s);
$build_vars = [ $build_vars ] unless (ref($build_vars));
foreach (@$build_vars) {
next if /^$/;
my ($n, $v) = split(/\s*=\s*/);
if (defined $item{$n}) {
carp("[ $node_id, $n ] already exists");
} else {
$item{$n} = 1;
$sth->execute($node_id, $n, $v) ||
croak("[ $node_id, $_ ] " . $dbh->errstr);
}
}
$sth->finish;
}
#_______________________________________
sub insertNode {
my $self = shift; (@_ & 1) && croak("Odd number of parameters.");
my %opt = @_;
my $ecd = $opt{ecd} || croak('ecd => REQUIRED!');
# insert into node table
my $node = $self->hashrefFromECD($ecd);
my $s = $self->buildInsertStatement(table => "node", data => $node);
my $dbh = $self->{dbh};
my $sth = $dbh->prepare($s);
$sth->execute || do { $self->rollbackAndCroak($s) };
$sth->finish;
my $id = $node->{node_id} = $self->currval('node_node_id_seq');
# insert aggregate attributes
eval {
$self->insertProvides($ecd->provides, $id);
$self->insertKeeplist($ecd->keeplist, $id);
$self->insertBuildVars($ecd->build_vars, $id);
};
if ($@) { $self->rollbackAndCroak($@) }
# insert into node_parent table
my $np = { node_id => $id, parent_id => $opt{parent_id} };
my $s2 = $self->buildInsertStatement(table=> "node_parent", data=> $np);
my $sth2 = $dbh->prepare($s2);
$sth2->execute || do { $self->rollbackAndCroak($s2) };
$sth2->finish;
# insert into node_distro_table
$self->relateNode(node => $node, distro => $self->{distro});
$dbh->commit;
return $node;
}
# XXX : deal w/ aggregate attributes
#_______________________________________
sub updateNode {
my $self = shift; (@_ & 1) && croak("Odd number of parameters.");
my %opt = @_;
my $ecd = $opt{ecd} || croak('ecd => REQUIRED!');
my $node = $self->hashrefFromECD($ecd);
$node->{node_id} = $opt{node_id} || croak('node_id => REQUIRED!');
my $s = $self->buildUpdateStatement(
table => "node",
data => $node,
primary_key => "node_id",
);
my $dbh = $self->{dbh};
my $sth = $dbh->prepare($s);
$sth->execute || do { $self->rollbackAndCroak($s) };
$sth->finish;
# nuke aggregate attributes from orbit (it's the only way to be sure)
# insert aggregate attributes XXX
$dbh->commit;
return $node;
}
# Create a hashref suitable for insertion into the node table.
# This does NOT handle aggregates (but it does handle the range pair).
#_______________________________________
my @node_attribute = qw(
value type default_value range help prompt srpm specpatch
requires requiresexpr
);
my @node_eval_attribute = qw(
static_size min_dynamic_size storage_size startup_time
);
sub hashrefFromECD {
my $self = shift;
my $ecd = shift;
my %node = (
node_class => $ecd->getNodeClass(),
node_name => $ecd->name(),
);
my $attr;
foreach (@node_attribute) {
if (defined($attr = $ecd->getAttribute($_))) {
if (ref($attr)) {
$attr = join("\n", @$attr);
}
if ($_ eq "range") {
my ($x, $y) = split($attr, ":"); # turn it into a pg array
$attr = "{$x, $y}";
}
$node{$_} = $attr;
}
}
foreach (@node_eval_attribute) {
if (defined($attr = $ecd->getAttribute($_))) {
my $eval_method = "eval_$_";
my ($size, $give_or_take) = $ecd->$eval_method();
$attr = "{$size, $give_or_take}";
$node{$_} = $attr;
}
}
if (defined $node{type}) {
$node{value_type} = $node{type};
delete($node{type});
}
warn("$node{node_name} has a requires and requiresexpr which is bad.")
if (defined $node{requires} && defined($node{requiresexpr}));
if (defined $node{requires}) {
$node{requires_type} = 'list';
}
if (defined $node{requiresexpr}) {
$node{requires_type} = 'expr';
$node{requires} = $node{requiresexpr};
delete($node{requiresexpr});
};
return \%node;
}
# add info in $ecd to current working distribution
#_______________________________________
sub updateDistro {
my $self = shift; (@_ & 1) && croak("Odd number of parameters.");
my %opt = @_;
my $ecd = $opt{ecd} || croak("ecd => REQUIRED!");
my $parent_id = $opt{parent_id} || undef;
my ($child, $node);
unless (defined($self->{distro})) {
croak("Cannot add an ECD until a distribution to work on is selected.");
}
if ($ecd->getDepth == 0) {
# handle root nodes (root node identification could be more robust)
$node = { };
$node->{node_id} = $self->{distro}{root_node_id};
} else {
# all other nodes
$node = $self->selectNode(
name => $ecd->name(),
parent_id => $parent_id,
);
if (defined($node)) {
$node = $self->updateNode(ecd => $ecd, node_id => $node->{node_id});
} else {
$node = $self->insertNode(ecd => $ecd, parent_id => $parent_id);
};
}
foreach $child ($ecd->getChildren) {
$self->updateDistro(ecd => $child, parent_id => $node->{node_id});
}
}
# get node_id for a given path
#_______________________________________
sub getIdForPath {
my $self = shift;
my $path = shift;
}
# return full path of a node
#_______________________________________
sub getNodePath {
my $self = shift;
my $id = shift;
my $p = $self->{path_cache};
my $root_node_id = $self->{distro}{root_node_id};
if ($id == $root_node_id) {
return '/';
}
my $distro_id = $self->{distro}{distro_id};
unless (defined $p->{$id}) {
my $q = qq{
select n.node_id, n.node_name, np.parent_id
from node n,
node_parent np,
node_distro nd
where n.node_id = np.node_id
( run in 0.654 second using v1.01-cache-2.11-cpan-39bf76dae61 )