Embedix-DB

 view release on metacpan or  search on metacpan

DB/Pg.pm  view on Meta::CPAN

    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 )