Skip to content

Commit

Permalink
Merge pull request #4 from CBIIT/get_all_db_models
Browse files Browse the repository at this point in the history
add all models from db
  • Loading branch information
majensen authored Jun 1, 2020
2 parents 962c286 + f9e2a8a commit 22dd2f9
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 1 deletion.
10 changes: 10 additions & 0 deletions perl/lib/Bento/Meta.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ This class is just a [Bento::Meta::Model](/perl/lib/Bento/Meta/Model.md) factory
Load a model from MDF files, or from a Neo4j database. `$bolt_url` must
use the `bolt://` scheme.

- list\_db\_models($bolt\_url)

Lists all of the models found in a Neo4j database. `$bolt_url` must
use the `bolt://` scheme.

- load\_\_all\_db\_models($bolt\_url)

Loads all models found in a Neo4j database. C<$bolt_url> must
use the C<bolt://> scheme.

- model($handle)

The [Bento::Meta::Model](/perl/lib/Bento/Meta/Model.md) object corresponding to the handle.
Expand Down
51 changes: 50 additions & 1 deletion perl/lib/Bento/Meta.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use Try::Tiny;
use Log::Log4perl qw/:easy/;
use strict;
use warnings;
no warnings qw/regexp/;

our $VERSION = "0.1";
our $VERSION = "0.2";

our $re_url = qr{^(?:https?|bolt)://};

Expand Down Expand Up @@ -42,6 +43,44 @@ sub load_model {
return $self->{_models}{$handle} = $model;
}

# just get the list of models (model handles) in database - do not load them!
sub list_db_models {
my $self = shift;
my ($connection) = @_;

# return value, will hold found models in db
my @db_model_handles = ();

# connect to neo4j
my $bolt_cxn = Neo4j::Bolt->connect($connection);
unless ($bolt_cxn->connected) {
LOGDIE ref($self)."::get_db_handle : Can't connect! ".$bolt_cxn->errmsg;
return;
}
# retrieve all model handles from db
my $qry = "MATCH (n:node) RETURN DISTINCT n.model";
my $stream = $bolt_cxn->run_query($qry, {});
while (my @results = $stream->fetch_next ) {
push @db_model_handles, $results[0];
}

return @db_model_handles;
}

# load all the database models
sub load_all_db_models{
my $self = shift;
my ($connection) = @_;

my @db_handles = $self->list_db_models($connection);

foreach my $handle (@db_handles){
$self->load_model($handle, $connection);
}

return @db_handles;
}

sub model { $_[0]->{_models}{$_[1]} };
sub models { values %{shift->{_models}} };
sub handles { sort keys %{shift->{_models}} };
Expand Down Expand Up @@ -75,6 +114,16 @@ This class is just a L<Bento::Meta::Model> factory and container.
Load a model from MDF files, or from a Neo4j database. C<$bolt_url> must
use the C<bolt://> scheme.
=item list_db_models($bolt_url)
Lists all of the models found in a Neo4j database. C<$bolt_url> must
use the C<bolt://> scheme.
=item load_all_db_models($bolt_url)
Loads all models found in a Neo4j database. C<$bolt_url> must
use the C<bolt://> scheme.
=item model($handle)
The L<Bento::Meta::Model> object corresponding to the handle.
Expand Down
71 changes: 71 additions & 0 deletions perl/t/010_meta__load_all_db_models.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use Test::More tests => 9;
use Test::Warn;
use Test::Deep;
use Test::Exception;
use IPC::Run qw/run/;
use Neo4j::Bolt;
use lib '../lib';
use Log::Log4perl qw/:easy/;
use Bento::Meta;

# --------------------
# Desc:
# tests the Bento::Meta::load_all_db_models()
# broke out from 009_meta.t so that db loaded models would not conflict
# with file loaded models (cannot load two models named ICDC)

Log::Log4perl->easy_init($FATAL);
my $ctr_name = "test$$";
my $img = 'maj1/test-db-bento-meta';
my $d = (-e 't' ? 't' : '.');

####
diag "Starting docker container '$ctr_name' with image $img";
my @startcmd = split / /,
"docker run -d -P --name $ctr_name $img";
my @portcmd = split / /, "docker container port $ctr_name";
my @stopcmd = split / /,"docker kill $ctr_name";
my @rmcmd = split / /, "docker rm $ctr_name";

my ($in, $out, $err);
unless (run(['docker'],'<pty<',\$in,'>pty>',\$out)) {
plan skip_all => "Docker not available for test database setup: skipping.";
}
run \@startcmd, \$in, \$out, \$err;
if ($err) {
diag "docker error: $err";
}
else {
sleep 10;
}
$in=$err=$out='';
run \@portcmd, \$in, \$out, \$err;
my ($port) = grep /7687.tcp/, split /\n/,$out;
($port) = $port =~ m/([0-9]+)$/;
####

ok my $cxn = Neo4j::Bolt->connect("bolt://localhost:$port"), 'create neo4j connection';
SKIP : {
skip "Can't connect to test db: ".$cxn->errmsg, 1 unless $cxn->connected;
$meta = Bento::Meta->new, 'can create new Bento::Meta instance';

# test the models found in the database
ok my @actual_models = $meta->list_db_models("bolt://localhost:$port"), "list models from db";
is_deeply [sort @actual_models], [qw/CTDC ICDC/], "correct handles";
is scalar $meta->models, 0, "no models were loaded";

# test that load_all_db_models can load 2 models: ICDC and CTDC
ok my $model_count = $meta->load_all_db_models("bolt://localhost:$port"), "loads all models from db";
is scalar $meta->models, 2, "meta now has expected number of models";
isa_ok($meta->model('ICDC'), 'Bento::Meta::Model');
isa_ok($meta->model('CTDC'), 'Bento::Meta::Model');
ok !$meta->model('boog'), 'make sure uncreated model doesnt exist';
}
done_testing;

END {
diag "Stopping container $ctr_name";
run \@stopcmd;
diag "Removing container $ctr_name";
run \@rmcmd;
}

0 comments on commit 22dd2f9

Please sign in to comment.