AnalysisAdaptor.pm 21.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
=head1 LICENSE

  Copyright (c) 1999-2009 The European Bioinformatics Institute and
  Genome Research Limited.  All rights reserved.

  This software is distributed under a modified Apache license.
  For license details, please see

    http://www.ensembl.org/info/about/code_licence.html

=head1 CONTACT

  Please email comments or questions to the public Ensembl
  developers list at <ensembl-dev@ebi.ac.uk>.

  Questions may also be sent to the Ensembl help desk at
  <helpdesk@ensembl.org>.

=cut
Arne Stabenau's avatar
Arne Stabenau committed
20 21 22

=head1 NAME

23
Bio::EnsEMBL::DBSQL::AnalysisAdaptor
Arne Stabenau's avatar
Arne Stabenau committed
24 25 26

=head1 SYNOPSIS

27
  use Bio::EnsEMBL::Registry;
28

29
  Bio::EnsEMBL::Registry->load_registry_from_db(
30 31
    -host => 'ensembldb.ensembl.org',
    -user => 'anonymous'
32
  );
33

34 35
  $analysis_adaptor =
    Bio::EnsEMBL::Registry->get_adaptor( "human", "core", "analysis" );
36 37

  my $analysis = $analysis_adaptor->fetch_by_logic_name('genscan');
Arne Stabenau's avatar
Arne Stabenau committed
38 39

=head1 DESCRIPTION
40

Arne Stabenau's avatar
Arne Stabenau committed
41 42 43
  Module to encapsulate all db access for persistent class Analysis.
  There should be just one per application and database connection.

44
=head1 METHODS
Arne Stabenau's avatar
Arne Stabenau committed
45 46 47 48 49 50

=cut


package Bio::EnsEMBL::DBSQL::AnalysisAdaptor;

51
use Bio::EnsEMBL::Analysis;
52
use Bio::EnsEMBL::DBSQL::BaseAdaptor;
53
use Bio::EnsEMBL::Utils::Exception;
Arne Stabenau's avatar
Arne Stabenau committed
54 55 56 57

use vars qw(@ISA);
use strict;

58 59
@ISA = qw( Bio::EnsEMBL::DBSQL::BaseAdaptor);

Arne Stabenau's avatar
Arne Stabenau committed
60

61 62
=head2 new

63 64 65 66 67 68 69 70
  Args       : Bio::EnsEMBL::DBSQL::DBAdaptor
  Example    : my $aa = new Bio::EnsEMBL::DBSQL::AnalysisAdaptor();
  Description: Creates a new Bio::EnsEMBL::DBSQL::AnalysisAdaptor object and
               internally loads and caches all the Analysis objects from the 
               database.
  Returntype : Bio::EnsEMBL::DBSQL::AnalysisAdaptor
  Exceptions : none
  Caller     : Bio::EnsEMBL::DBSQL::DBAdaptor
71
  Status     : Stable
72 73 74

=cut

Arne Stabenau's avatar
Arne Stabenau committed
75
sub new {
76
  my ($class, $db) = @_;
Arne Stabenau's avatar
Arne Stabenau committed
77

78
  my $self = $class->SUPER::new($db);
79

80
  #load and cache all of the Analysis objects
Arne Stabenau's avatar
Arne Stabenau committed
81
  $self->fetch_all;
82

Arne Stabenau's avatar
Arne Stabenau committed
83 84 85
  return $self;
}

86

Arne Stabenau's avatar
Arne Stabenau committed
87 88
=head2 fetch_all

89 90 91 92
  Args       : none
  Example    : my @analysis = $analysis_adaptor->fetch_all()
  Description: fetches all of the Analysis objects from the database and caches
               them internally.
Graham McVicker's avatar
Graham McVicker committed
93
  Returntype : listref of Bio::EnsEMBL::Analysis retrieved from the database
94 95
  Exceptions : none
  Caller     : AnalysisAdaptor::new
96
  Status     : Stable
Arne Stabenau's avatar
Arne Stabenau committed
97 98 99 100 101 102 103 104 105

=cut

sub fetch_all {
  my $self = shift;
  my ( $analysis, $dbID );
  my $rowHashRef;

  $self->{_cache} = {};
106
  $self->{_logic_name_cache} = {};
107

Arne Stabenau's avatar
Arne Stabenau committed
108
  my $sth = $self->prepare( q {
109
    SELECT analysis.analysis_id, logic_name,
Simon Potter's avatar
Simon Potter committed
110 111 112 113
           program, program_version, program_file,
           db, db_version, db_file,
           module, module_version,
           gff_source, gff_feature,
Glenn Proctor's avatar
Glenn Proctor committed
114
           created, parameters, description, display_label, displayable, web_data
115 116 117
    FROM   analysis
    LEFT JOIN analysis_description
    ON analysis.analysis_id = analysis_description.analysis_id } );
Arne Stabenau's avatar
Arne Stabenau committed
118 119 120 121
  $sth->execute;

  while( $rowHashRef = $sth->fetchrow_hashref ) {
    my $analysis = $self->_objFromHashref( $rowHashRef  );
122 123

    $self->{_cache}->{$analysis->dbID}                    = $analysis;
124
    $self->{_logic_name_cache}->{lc($analysis->logic_name())} = $analysis;
Arne Stabenau's avatar
Arne Stabenau committed
125 126
  }

127 128 129
  my @ana = values %{$self->{_cache}};

  return \@ana;
Arne Stabenau's avatar
Arne Stabenau committed
130 131
}

132

133 134 135 136 137 138 139 140 141
=head2 fetch_all_by_feature_class

  Arg [1]    : string $feature_cless - The name of the feature class
  Example    : my @analyses = @{$analysis_adaptor->fetch_all_by_feature_class('Gene');
  Description: Returns all analyses that correspond to a given 
               feature class; see feature_classes method for a list.
  Returntype : Listref of Bio::EnsEMBL::Analysis
  Exceptions : none
  Caller     : general
142
  Status     : Stable
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

=cut

sub fetch_all_by_feature_class {
  my $self = shift;
  my $feat_class = shift || throw( "Need a feature type, e.g. SimpleFeature" );
 
  my @feature_classes = $self->feature_classes; # List of all feature classes
  my %feat_table_map;
  foreach my $class( @feature_classes ){
    # Map e.g. DnaAlignFeature to dna_align_feature
    my $table = join( "_", map lc, ( $class =~ /([A-Z][a-z]+)/g ) );
    $feat_table_map{$class} = $table;
  }
  $feat_table_map{DensityFeature}='density_type'; # analysis_id in diff table
158 159
  my $feat_table = $feat_table_map{$feat_class} || 
      ( warning( "No feature type corresponding to $feat_class" ) &&
160 161 162
        return [] );

  my $sql_t = qq|
Will Spooner's avatar
Will Spooner committed
163
SELECT DISTINCT analysis_id FROM %s |;
164 165 166 167 168
  
  my $sql = sprintf( $sql_t, $feat_table );
  my $sth = $self->prepare( $sql );
  my $rv  = $sth->execute();
  my $res = $sth->fetchall_arrayref;
169 170 171 172 173 174 175 176
  my @analyses;
  foreach my $r( @{$res} ){
    my $analysis = $self->fetch_by_dbID($r->[0]) 
        || throw( "analysis_id $r->[0] from $feat_table table "
                  . "is not in the analysis table!" );
    push @analyses, $analysis;
  }
  return [@analyses];
177 178 179 180 181 182 183 184 185 186 187 188
}


=head2 feature_classes

  Arg [1]    : NONE
  Example    : my @fclasses = $analysis_adaptor->feature_classes;
  Description: Returns a list of the different classes of Ensembl feature 
               object that have an analysis
  Returntype : List of feature classes
  Exceptions : none
  Caller     : general
189
  Status     : Stable
190 191 192 193 194 195 196 197 198 199

=cut

sub feature_classes{
  # Can't think of a way to do this programatically, so hard-coded
  return qw(
            DensityFeature
            DnaAlignFeature
            Gene
            MarkerFeature
200 201
            PredictionTranscript
            ProteinAlignFeature
202 203 204 205 206 207 208
            ProteinFeature
            QtlFeature
            RepeatFeature
            SimpleFeature
            );
}

Arne Stabenau's avatar
Arne Stabenau committed
209 210
=head2 fetch_by_dbID

211 212 213 214 215 216 217 218
  Arg [1]    : int $internal_analysis_id - the database id of the analysis 
               record to retrieve
  Example    : my $analysis = $analysis_adaptor->fetch_by_dbID(1);
  Description: Retrieves an Analysis object from the database via its internal
               id.
  Returntype : Bio::EnsEMBL::Analysis
  Exceptions : none
  Caller     : general
219
  Status     : Stable
220 221 222

=cut

Arne Stabenau's avatar
Arne Stabenau committed
223 224 225 226 227 228 229 230
sub fetch_by_dbID {
  my $self = shift;
  my $id = shift;

  if( defined $self->{_cache}->{$id} ) {
    return $self->{_cache}->{$id};
  }

Michele Clamp's avatar
Debug  
Michele Clamp committed
231
  my $query = q{
232
    SELECT analysis.analysis_id, logic_name,
Simon Potter's avatar
Simon Potter committed
233 234 235 236
           program, program_version, program_file,
           db, db_version, db_file,
           module, module_version,
           gff_source, gff_feature,
Glenn Proctor's avatar
Glenn Proctor committed
237
           created, parameters, description, display_label, displayable, web_data
Simon Potter's avatar
Simon Potter committed
238
    FROM   analysis
239 240 241
    LEFT JOIN analysis_description
    ON analysis.analysis_id = analysis_description.analysis_id
    WHERE  analysis.analysis_id = ? };
Michele Clamp's avatar
Debug  
Michele Clamp committed
242

243
  my $sth = $self->prepare($query);
244 245
  $sth->bind_param(1,$id,SQL_INTEGER);
  $sth->execute();
Arne Stabenau's avatar
Arne Stabenau committed
246 247 248 249 250 251 252
  my $rowHashRef = $sth->fetchrow_hashref;
  if( ! defined $rowHashRef ) {
    return undef;
  }

  my $anal = $self->_objFromHashref( $rowHashRef );
  $self->{_cache}->{$anal->dbID} = $anal;
253
  $self->{_logic_name_cache}->{lc($anal->logic_name())} = $anal;
Arne Stabenau's avatar
Arne Stabenau committed
254 255 256
  return $anal;
}

257

258
=head2 fetch_by_logic_name
259

260 261 262 263 264 265 266
  Arg [1]    : string $logic_name the logic name of the analysis to retrieve
  Example    : my $analysis = $a_adaptor->fetch_by_logic_name('Eponine');
  Description: Retrieves an analysis object from the database using its unique
               logic name.
  Returntype : Bio::EnsEMBL::Analysis
  Exceptions : none
  Caller     : general
267
  Status     : Stable
268 269 270

=cut

Arne Stabenau's avatar
Arne Stabenau committed
271
sub fetch_by_logic_name {
272 273
  my ( $self, $logic_name ) = @_;

Arne Stabenau's avatar
Arne Stabenau committed
274 275 276
  my $analysis;
  my $rowHash;

277 278 279
  # Check the cache for the logic name
  if ( defined( $self->{_logic_name_cache}{ lc($logic_name) } ) ) {
    return $self->{_logic_name_cache}{ lc($logic_name) };
280 281
  }

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
  my $sth = $self->prepare(
    qq(
SELECT  analysis.analysis_id,
        logic_name,
        program,
        program_version,
        program_file,
        db,
        db_version,
        db_file,
        module,
        module_version,
        gff_source,
        gff_feature,
        created,
        parameters,
        description,
        display_label,
        displayable,
        web_data
FROM    analysis
  LEFT JOIN analysis_description
    ON  ( analysis.analysis_id = analysis_description.analysis_id )
WHERE  LOWER(logic_name) = ?)
  );
307

308
  $sth->bind_param( 1, lc($logic_name), SQL_VARCHAR );
309
  $sth->execute();
310
  my $rowHashRef = $sth->fetchrow_hashref();
311

312
  if ( !defined($rowHashRef) ) { return undef }
313

314
  $analysis = $self->_objFromHashref($rowHashRef);
315

316 317 318 319
  # place the analysis in the caches, cross referenced by dbID and
  # logic_name
  $self->{_cache}->{ $analysis->dbID() } = $analysis;
  $self->{_logic_name_cache}->{ lc($logic_name) } = $analysis;
320

321
  return $analysis;
322
} ## end sub fetch_by_logic_name
Arne Stabenau's avatar
Arne Stabenau committed
323

324 325 326

=head2 store

327
  Arg [1]    : Bio:EnsEMBL::Analysis $analysis
328
  Example    : $analysis_adaptor->store($analysis);
329 330 331
  Description: Stores $analysis in db.  If the analysis is already stored in
               the database its dbID and adaptor are updated, but the analysis
               is not stored a second time.
332 333
               Sets created date if not already set. Sets dbID and adaptor
               inside $analysis. Returns dbID.
334 335 336 337
  Returntype : int - dbID of stored analysis
  Exceptions : throw on incorrect argument
               throw if analysis argument does not have a logic name
  Caller     : general
338
  Status     : Stable
339 340 341

=cut

Arne Stabenau's avatar
Arne Stabenau committed
342 343 344
sub store {
  my $self = shift;
  my $analysis = shift;
345

346 347
  if(!ref($analysis) || !$analysis->isa('Bio::EnsEMBL::Analysis')) {
    throw("Bio::EnsEMBL::Analysis argument expected.");
348 349
  }

350 351
  if($analysis->is_stored($self->db())) {
    return $analysis->dbID();
352
  }
353

354 355
  if(!$analysis->logic_name()) {
    throw("Analysis cannot be stored without a valid logic_name");
356
  }
357
    
358 359 360 361

  my $rows_inserted = 0;
  my $sth;

Laura Clarke's avatar
 
Laura Clarke committed
362
  if($analysis->created ) {
363 364 365 366 367 368 369

    # we use insert IGNORE so that this method can be used in a multi-process
    # environment.  If another process has already written this record
    # then there will not be a problem

    $sth = $self->prepare( q{
      INSERT IGNORE INTO analysis
Arne Stabenau's avatar
Arne Stabenau committed
370 371
      SET created = ?,
          logic_name = ?,
372 373
	        db = ?,
	        db_version = ?,
Arne Stabenau's avatar
Arne Stabenau committed
374 375 376 377
          db_file = ?,
          program = ?,
          program_version = ?,
          program_file = ?,
378
	        parameters = ?,
Arne Stabenau's avatar
Arne Stabenau committed
379 380 381
          module = ?,
          module_version = ?,
          gff_source = ?,
382 383 384
          gff_feature = ?

			    } );
385 386 387 388 389 390 391 392 393 394 395 396 397 398
    $sth->bind_param(1,$analysis->created,SQL_DATETIME);
    $sth->bind_param(2,$analysis->logic_name,SQL_VARCHAR);
    $sth->bind_param(3,$analysis->db,SQL_VARCHAR);
    $sth->bind_param(4,$analysis->db_version,SQL_VARCHAR);
    $sth->bind_param(5,$analysis->db_file,SQL_VARCHAR);
    $sth->bind_param(6,$analysis->program,SQL_VARCHAR);
    $sth->bind_param(7,$analysis->program_version,SQL_VARCHAR);
    $sth->bind_param(8,$analysis->program_file,SQL_VARCHAR);
    $sth->bind_param(9,$analysis->parameters,SQL_VARCHAR);
    $sth->bind_param(10,$analysis->module,SQL_VARCHAR);
    $sth->bind_param(11,$analysis->module_version,SQL_VARCHAR);
    $sth->bind_param(12,$analysis->gff_source,SQL_VARCHAR);
    $sth->bind_param(13,$analysis->gff_feature,SQL_VARCHAR);
    $rows_inserted = $sth->execute();
Arne Stabenau's avatar
Arne Stabenau committed
399

400 401 402
  } else {
    $sth = $self->prepare( q{
      INSERT IGNORE INTO analysis
Arne Stabenau's avatar
Arne Stabenau committed
403 404
      SET created = now(),
          logic_name = ?,
405 406
          db = ?,
          db_version = ?,
Arne Stabenau's avatar
Arne Stabenau committed
407 408 409 410
          db_file = ?,
          program = ?,
          program_version = ?,
          program_file = ?,
411
	        parameters = ?,
Arne Stabenau's avatar
Arne Stabenau committed
412 413 414
          module = ?,
          module_version = ?,
          gff_source = ?,
415 416
          gff_feature = ?
	 } );
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
    
    $sth->bind_param(1,$analysis->logic_name,SQL_VARCHAR);
    $sth->bind_param(2,$analysis->db,SQL_VARCHAR);
    $sth->bind_param(3,$analysis->db_version,SQL_VARCHAR);
    $sth->bind_param(4,$analysis->db_file,SQL_VARCHAR);
    $sth->bind_param(5,$analysis->program,SQL_VARCHAR);
    $sth->bind_param(6,$analysis->program_version,SQL_VARCHAR);
    $sth->bind_param(7,$analysis->program_file,SQL_VARCHAR);
    $sth->bind_param(8,$analysis->parameters,SQL_VARCHAR);
    $sth->bind_param(9,$analysis->module,SQL_VARCHAR);
    $sth->bind_param(10,$analysis->module_version,SQL_VARCHAR);
    $sth->bind_param(11,$analysis->gff_source,SQL_VARCHAR);
    $sth->bind_param(12,$analysis->gff_feature,SQL_VARCHAR);

    $rows_inserted = $sth->execute();
432
  }
Arne Stabenau's avatar
Arne Stabenau committed
433

434 435 436
  my $dbID;
  # if we need to fetch the timestamp, or the insert failed due to existance
  # of an existing entry, we need to retrieve the entry from the db
437
  # note: $sth->execute can return 0E0 on error which is zero, but true
438 439
  # which is why the $rows_inserted clause was added.
  if(!$analysis->created() || !$rows_inserted || $rows_inserted == 0) {
440 441 442 443 444
    my $new_analysis = $self->fetch_by_logic_name($analysis->logic_name);

    if(!$new_analysis) {
      throw("Could not retrieve just stored analysis from database.\n" .
            "Possibly incorrect db permissions or missing analysis table\n");
Arne Stabenau's avatar
Arne Stabenau committed
445
    }
446 447 448

    $dbID = $new_analysis->dbID();
    $analysis->created($new_analysis->created());
449 450 451 452
  } 
  
  $dbID ||= $sth->{'mysql_insertid'};
  $sth->finish();
453

454
  # store description and display_label
455
  if( defined( $analysis->description() ) || defined( $analysis->display_label() )|| defined( $analysis->web_data() )) {
Glenn Proctor's avatar
Glenn Proctor committed
456
      $sth = $self->prepare( "INSERT IGNORE INTO analysis_description (analysis_id, display_label, description, displayable, web_data) VALUES (?,?,?,?, ?)");
457 458 459 460

      $sth->bind_param(1,$dbID,SQL_INTEGER);
      $sth->bind_param(2,$analysis->display_label(),SQL_VARCHAR);
      $sth->bind_param(3,$analysis->description,SQL_LONGVARCHAR);
461
      $sth->bind_param(4,$analysis->displayable,SQL_TINYINT);
462 463 464
      #$sth->bind_param(5,$analysis->web_data(),SQL_LONGVARCHAR);
      my $web_data;
      $web_data = $self->dump_data($analysis->web_data()) if ($analysis->web_data());
465
      $sth->bind_param(5,$web_data,SQL_LONGVARCHAR);
466 467
      $sth->execute();

468
      $sth->finish();
Arne Stabenau's avatar
Arne Stabenau committed
469
  }
470
  
471 472


Arne Stabenau's avatar
Arne Stabenau committed
473
  $self->{_cache}->{$dbID} = $analysis;
474
  $self->{_logic_name_cache}{lc($analysis->logic_name)} = $analysis;
Arne Stabenau's avatar
Arne Stabenau committed
475

476 477
  $analysis->adaptor( $self );
  $analysis->dbID( $dbID );
478

Arne Stabenau's avatar
Arne Stabenau committed
479 480 481
  return $dbID;
}

482 483


Simon Potter's avatar
Simon Potter committed
484 485 486 487 488
=head2 update

  Arg [1]    : Bio::EnsEMBL::Analysis $anal
  Example    : $adaptor->update($anal)
  Description: Updates this analysis in the database
489 490
  Returntype : int 1 if update is performed, undef if it is not
  Exceptions : throw if arg is not an analysis object
Simon Potter's avatar
Simon Potter committed
491
  Caller     : ?
492
  Status     : Stable
Simon Potter's avatar
Simon Potter committed
493 494 495 496

=cut

sub update {
497 498
  my $self = shift;
  my $a    = shift;
Simon Potter's avatar
Simon Potter committed
499

500 501 502
  if (!ref($a) || !$a->isa('Bio::EnsEMBL::Analysis')) {
    throw("Expected Bio::EnsEMBL::Analysis argument.");
  }
Simon Potter's avatar
Simon Potter committed
503

504
  if(!$a->is_stored($self->db())) {
Simon Potter's avatar
Simon Potter committed
505 506 507
    return undef;
  }

508 509 510 511 512
  my $sth = $self->prepare
    ("UPDATE analysis " .
     "SET created = ?, logic_name = ?, db = ?, db_version = ?, db_file = ?, ".
     "    program = ?, program_version = ?, program_file = ?,  ".
     "    parameters = ?, module = ?, module_version = ?, ".
513
     "    gff_source = ?, gff_feature = ? " .
514
     "WHERE analysis_id = ?");
Simon Potter's avatar
Simon Potter committed
515

516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533


  $sth->bind_param(1,$a->created,SQL_DATETIME);
  $sth->bind_param(2,$a->logic_name,SQL_VARCHAR);
  $sth->bind_param(3,$a->db,SQL_VARCHAR);
  $sth->bind_param(4,$a->db_version,SQL_VARCHAR);
  $sth->bind_param(5,$a->db_file,SQL_VARCHAR);
  $sth->bind_param(6,$a->program,SQL_VARCHAR);
  $sth->bind_param(7,$a->program_version,SQL_VARCHAR);
  $sth->bind_param(8,$a->program_file,SQL_VARCHAR);
  $sth->bind_param(9,$a->parameters,SQL_VARCHAR);
  $sth->bind_param(10,$a->module,SQL_VARCHAR);
  $sth->bind_param(11,$a->module_version,SQL_VARCHAR);
  $sth->bind_param(12,$a->gff_source,SQL_VARCHAR);
  $sth->bind_param(13,$a->gff_feature,SQL_VARCHAR);
  $sth->bind_param(14,$a->dbID,SQL_INTEGER);

  $sth->execute();
Simon Potter's avatar
Simon Potter committed
534

535 536
  $sth->finish();

537 538 539 540
  # also update description & display label - may need to create these if
  # not already there
  $sth = $self->prepare("SELECT description FROM analysis_description WHERE analysis_id= ?");
  $sth->execute($a->dbID);
541
  my $web_data; #this is an anonymous reference to a hash, will have to be dumped into string before writing to db
542
  if ($sth->fetchrow_hashref) { # update if exists
543
      $web_data = $self->dump_data($a->web_data()) if ($a->web_data());
544
      $sth = $self->prepare
Glenn Proctor's avatar
Glenn Proctor committed
545
      ("UPDATE analysis_description SET description = ?, display_label = ?, displayable = ?, web_data = ? WHERE analysis_id = ?");
546 547 548 549 550 551 552
      $sth->bind_param(1,$a->description,SQL_LONGVARCHAR);     
      $sth->bind_param(2,$a->display_label(),SQL_VARCHAR);
      $sth->bind_param(3,$a->displayable,SQL_TINYINT);
      #      print "after $web_data\n";
      $sth->bind_param(4,$web_data,SQL_LONGVARCHAR);
      $sth->bind_param(5,$a->dbID,SQL_INTEGER);
      $sth->execute();
553 554 555

  } else { # create new entry

556
    if( $a->description() || $a->display_label() || $a->web_data) {
557
	$web_data = $self->dump_data($a->web_data()) if ($a->web_data());
558
      #my $web_data = $self->dump_data($a->web_data());
Glenn Proctor's avatar
Glenn Proctor committed
559
      $sth = $self->prepare( "INSERT IGNORE INTO analysis_description (analysis_id, display_label, description, displayable, web_data) VALUES (?,?,?,?,?)");
560 561 562 563 564 565 566 567
	$sth->bind_param(1,$a->dbID,SQL_INTEGER);	
	$sth->bind_param(2,$a->display_label(),SQL_VARCHAR);
	$sth->bind_param(3,$a->description,SQL_LONGVARCHAR);     
	$sth->bind_param(4,$a->displayable,SQL_TINYINT);
	#my $web_data = $self->dump_data($a->web_data());
	$sth->bind_param(5,$web_data,SQL_LONGVARCHAR);
	$sth->execute();

568 569 570 571 572 573
    }

  }


    $sth->finish();
574

575 576 577
  # the logic_name cache needs to be re-updated now, since we may have just
  # changed the logic_name
  $self->fetch_all();
Simon Potter's avatar
Simon Potter committed
578 579 580 581 582 583 584 585 586 587

  return 1;
}



=head2 remove

  Arg [1]    : Bio::EnsEMBL::Analysis $anal
  Example    : $adaptor->remove($anal)
588 589 590 591
  Description: Removes this analysis from the database.  This is not really
               safe to execute in a multi process environment, so programs
               should not remove analysis while out on the farm.
  Returntype : none
Simon Potter's avatar
Simon Potter committed
592 593
  Exceptions : thrown if $anal arg is not an analysis object
  Caller     : ?
594
  Status     : Stable
Simon Potter's avatar
Simon Potter committed
595 596 597 598 599

=cut

sub remove {
  my ($self, $analysis) = @_;
600

Simon Potter's avatar
Simon Potter committed
601
  if (!defined $analysis || !ref $analysis) {
602
    throw("called remove on AnalysisAdaptor with a [$analysis]");
Simon Potter's avatar
Simon Potter committed
603 604
  }

605
  if(!$analysis->is_stored($self->db())) {
Simon Potter's avatar
Simon Potter committed
606 607 608
    return undef;
  }

609
  my $sth = $self->prepare("DELETE FROM analysis WHERE analysis_id = ?");
610 611
  $sth->bind_param(1,$analysis->dbID,SQL_INTEGER);
  $sth->execute();
612 613 614

  $sth = $self->prepare("DELETE FROM analysis_description WHERE analysis_id = ?");
  $sth->execute($analysis->dbID());
615 616 617 618 619 620 621 622 623 624 625

  # remove this analysis from the cache
  delete $self->{'_cache'}->{$analysis->dbID()};
  delete $self->{'_logic_name_cache'}->{lc($analysis->logic_name)};


  # unset the adaptor and dbID
  $analysis->dbID(undef);
  $analysis->adaptor(undef);

  return;
Simon Potter's avatar
Simon Potter committed
626 627 628 629
}



Arne Stabenau's avatar
Arne Stabenau committed
630 631
=head2 exists

632 633
  Arg [1]    : Bio::EnsEMBL::Analysis $anal
  Example    : if($adaptor->exists($anal)) #do something
634 635 636 637 638 639 640 641 642
  Description: Tests whether this Analysis already exists in the database
               by checking first if the adaptor and dbID are set and
               secondly by whether it is in this adaptors internal cache.
               Note that this will not actually check the database and will
               not find and analysis which were recently added by other
               processes.  You are better off simply trying to store an
               analysis which will reliably ensure that it is not stored twice
               in the database.
  Returntype : int dbID if analysis is found, otherwise returns undef
643
  Exceptions : thrown if $anal arg is not an analysis object
644
  Caller     : store
645
  Status     : Stable
Arne Stabenau's avatar
Arne Stabenau committed
646 647 648 649

=cut

sub exists {
650
  my ($self,$anal) = @_;
Arne Stabenau's avatar
Arne Stabenau committed
651

652 653
  if(!ref($anal) || !$anal->isa("Bio::EnsEMBL::Analysis")) {
    throw("Object is not a Bio::EnsEMBL::Analysis");
654
  }
655 656 657 658 659 660 661

  #if this analysis is stored in this db already return its dbID
  if($anal->is_stored($self->db())) {
    return $anal->dbID();
  }

  #this analysis object is not stored but one exactly like it may have been
662 663 664 665 666 667 668
  foreach my $cacheId (keys %{$self->{_cache}}) {
    if ($self->{_cache}->{$cacheId}->compare($anal) >= 0) {
      # $anal->dbID( $cacheId );
      # $anal->adaptor( $self );
      return $cacheId;
    }
  }
669 670

  #no analysis like this one exists in the database
671
  return undef;
Arne Stabenau's avatar
Arne Stabenau committed
672 673 674
}


675
=head2 _objFromHashref
Arne Stabenau's avatar
Arne Stabenau committed
676

677 678 679 680 681 682
  Arg [1]    : hashref $rowHash
  Description: Private helper function generates an Analysis object from a 
               mysql row hash reference.
  Returntype : Bio::EnsEMBL::Analysis
  Exceptions : none
  Caller     : Bio::EnsEMBL::DBSQL::AnalsisAdaptor::fetch_* methods
683
  Status     : Stable
Arne Stabenau's avatar
Arne Stabenau committed
684

685
=cut
686

Arne Stabenau's avatar
Arne Stabenau committed
687 688 689 690
sub _objFromHashref {
  my $self = shift;
  my $rowHash = shift;

691
  my $web_data = $rowHash->{web_data} ? $self->get_dumped_data($rowHash->{web_data}) : '';
Simon Potter's avatar
Simon Potter committed
692 693
  my $analysis = Bio::EnsEMBL::Analysis->new(
      -id              => $rowHash->{analysis_id},
694
      -adaptor         => $self,
Simon Potter's avatar
Simon Potter committed
695 696 697 698
      -db              => $rowHash->{db},
      -db_file         => $rowHash->{db_file},
      -db_version      => $rowHash->{db_version},
      -program         => $rowHash->{program},
Arne Stabenau's avatar
Arne Stabenau committed
699
      -program_version => $rowHash->{program_version},
Simon Potter's avatar
Simon Potter committed
700 701 702 703 704 705 706
      -program_file    => $rowHash->{program_file},
      -gff_source      => $rowHash->{gff_source},
      -gff_feature     => $rowHash->{gff_feature},
      -module          => $rowHash->{module},
      -module_version  => $rowHash->{module_version},
      -parameters      => $rowHash->{parameters},
      -created         => $rowHash->{created},
707 708
      -logic_name      => $rowHash->{logic_name},
      -description     => $rowHash->{description},
Glenn Proctor's avatar
Glenn Proctor committed
709
      -display_label   => $rowHash->{display_label},
Glenn Proctor's avatar
Glenn Proctor committed
710
      -displayable     => $rowHash->{displayable},
711
					     -web_data        => $web_data,
Arne Stabenau's avatar
Arne Stabenau committed
712
    );
713

Arne Stabenau's avatar
Arne Stabenau committed
714 715 716
  return $analysis;
}

717

Arne Stabenau's avatar
Arne Stabenau committed
718

719
1;