ensembl-hive  2.7.0
Database.pm
Go to the documentation of this file.
1 
2 =head1 LICENSE
3 
4 See the NOTICE file distributed with this work for additional information
5 regarding copyright ownership.
6 
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10 
11  http://www.apache.org/licenses/LICENSE-2.0
12 
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 
19 =cut
20 
21 package XrefParser::Database;
22 
23 use strict;
24 use warnings;
25 use Carp;
26 use DBI;
28 use File::Spec::Functions;
29 use IO::File;
30 use English;
31 use vars qw(@ISA);
32 use strict;
33 
35 
36 sub new {
37  my ( $proto, $arg_ref ) = @_;
38 
39  my $class = ref $proto || $proto;
40  my $self = bless {}, $class;
41 
42  $self->dbc(
43  ref $arg_ref eq 'Bio::EnsEMBL::DBSQL::DBConnection' ? $arg_ref :
45  -HOST => $arg_ref->{host},
46  -DBNAME => $arg_ref->{dbname},
47  -USER => $arg_ref->{user},
48  -PASS => $arg_ref->{pass} || '',
49  -PORT => $arg_ref->{port} || '3306'
50  ) );
51  $self->verbose( $arg_ref->{verbose} );
52 
53  return $self;
54 }
55 
56 sub verbose {
57  my ( $self, $arg ) = @_;
58 
59  ( defined $arg ) && ( $self->{_verbose} = $arg );
60  return $self->{_verbose};
61 }
62 
63 sub dbc {
64  my $self = shift;
65 
66  if (@_) {
67  my $arg = shift;
68 
69  if ( defined($arg) ) {
70  croak "$arg is not a DBConnection"
71  unless $arg->isa('Bio::EnsEMBL::DBSQL::DBConnection');
72  $self->{_dbc} = $arg;
73  }
74  }
75 
76  return $self->{_dbc};
77 }
78 
79 sub host {
80  my ( $self, $arg ) = @_;
81  $self->dbc->host($arg) if defined $arg;
82  return $self->dbc->host;
83 }
84 
85 sub dbname {
86  my ( $self, $arg ) = @_;
87  $self->dbc->dbname($arg) if defined $arg;
88  return $self->dbc->dbname;
89 }
90 
91 sub user {
92  my ( $self, $arg ) = @_;
93  $self->dbc->user($arg) if defined $arg;
94  return $self->dbc->user;
95 }
96 
97 sub pass {
98  my ( $self, $arg ) = @_;
99  $self->dbc->pass($arg) if defined $arg;
100  return $self->dbc->pass;
101 }
102 
103 sub port {
104  my ( $self, $arg ) = @_;
105  $self->dbc->port($arg) if defined $arg;
106  return $self->dbc->port;
107 }
108 
109 sub dbi {
110  my $self = shift;
111  my $dbi;
112 
113  if ( !defined $dbi || !$dbi->ping() ) {
114  my $connect_string =
115  sprintf( "dbi:mysql:host=%s;port=%s;database=%s",
116  $self->host, $self->port, $self->dbname );
117 
118  $dbi =
119  DBI->connect( $connect_string, $self->user, $self->pass,
120  { 'RaiseError' => 1 } ) or
121  croak( "Can't connect to database: " . $DBI::errstr );
122  $dbi->{'mysql_auto_reconnect'} = 1; # Reconnect on timeout
123  }
124  return $dbi;
125 }
126 
127 # Create database if required.
128 # Assumes sql/table.sql and sql/populate_metadata.sql are present.
129 sub create {
130  my ( $self, $sql_dir, $force, $drop_db, $preparse, $xref_source_dbi) = @_;
131  $self->recreate_database( $force, $drop_db );
132  $self->populate( $sql_dir, $force, $preparse, $xref_source_dbi);
133 }
134 
135 sub populate {
136  my ( $self, $sql_dir, $force, $preparse, $xref_source_dbi ) = @_;
137  my $table_file = catfile( $sql_dir, 'sql', 'table.sql' );
138  my $metadata_file = $self->prepare_metadata_file( $sql_dir, $force, $preparse );
139 
140  $self->populate_with_file($table_file);
141  $self->populate_with_file($metadata_file);
142 }
143 
144 sub copy_source_metadata_file {
145  my ( $self, $xref_source_dbi) = @_;
146 
147  my $metadata_file = "metadata_config.sql";
148  open(CONFIG, ">$metadata_file") or die "Can't open $metadata_file: $!";
149 
150  my $select_species_sth = $xref_source_dbi->prepare("SELECT species_id, taxonomy_id, name, aliases FROM species;");
151  my ($species_id, $taxonomy_id, $name, $aliases);
152  $select_species_sth->execute();
153  $select_species_sth->bind_columns(\$species_id, \$taxonomy_id, \$name, \$aliases);
154  while ($select_species_sth->fetch()) {
155  print CONFIG "INSERT INTO species (species_id, taxonomy_id, name, aliases) ".
156  " VALUES ('$species_id', '$taxonomy_id', '$name', '$aliases');";
157  print CONFIG "\n\n";
158  }
159  $select_species_sth->finish();
160 
161  my $select_source_sth = $xref_source_dbi->prepare("SELECT source_id, name, source_release, ordered, priority, priority_description, status FROM source");
162  my ($source_id, $source_release, $ordered, $priority, $priority_description, $status);
163  $select_source_sth->execute();
164  $select_source_sth->bind_columns(\$source_id, \$name, \$source_release, \$ordered, \$priority, \$priority_description, \$status);
165  while ($select_source_sth->fetch()) {
166  print CONFIG 'INSERT INTO source (source_id, name, source_release, ordered, priority, priority_description, status) ';
167  printf CONFIG (' VALUES (%d, "%s", "%s", %d, %d, "%s", "%s") ;',
168  $source_id, $name, $source_release, $ordered, $priority, $priority_description, $status);
169  print CONFIG "\n\n";
170  }
171  $select_source_sth->finish();
172 
173  my $select_dependent_sth = $xref_source_dbi->prepare("SELECT master_source_id, dependent_name FROM dependent_source");
174  my ($master_source_id, $dependent_name);
175  $select_dependent_sth->execute();
176  $select_dependent_sth->bind_columns(\$master_source_id, \$dependent_name);
177  while ($select_dependent_sth->fetch()) {
178  print CONFIG "INSERT IGNORE INTO dependent_source (master_source_id, dependent_name) ".
179  " VALUES ('$master_source_id', '$dependent_name');";
180  print CONFIG "\n\n";
181  }
182  $select_dependent_sth->finish();
183 
184  my $select_source_url_sth = $xref_source_dbi->prepare("SELECT source_url_id, source_id, species_id, parser FROM source_url");
185  my ($source_url_id, $parser);
186  $select_source_url_sth->execute();
187  $select_source_url_sth->bind_columns(\$source_url_id, \$source_id, \$species_id, \$parser);
188  while ($select_source_url_sth->fetch()) {
189  print CONFIG "INSERT INTO source_url (source_url_id, source_id, species_id, parser) ".
190  " VALUES ('$source_url_id', '$source_id', '$species_id', '$parser');";
191  print CONFIG "\n\n";
192  }
193  $select_source_url_sth->finish();
194 
195  close (CONFIG);
196  return $metadata_file;
197 }
198 
199 sub prepare_metadata_file {
200  my ( $self, $sql_dir, $force, $preparse ) = @_;
201 
202  $preparse = 0 if (!defined($preparse));
203 
204  my $metadata_file = catfile( $sql_dir, 'sql', "populate_metadata_$preparse.sql" );
205  my $ini_file = catfile( $sql_dir, 'xref_config.ini' );
206 
207  local $| = 1; # flush stdout
208 
209  # Figure out whether to run 'xref_config2sql.pl' or not by comparing
210  # the timestamps on 'xref_config.ini' and 'sql/populate_metadata.sql'.
211  my $ini_tm = ( stat $ini_file )[9];
212  my $meta_tm = ( stat $metadata_file )[9];
213 
214  if ( !defined($meta_tm) || $ini_tm > $meta_tm ) {
215  my $reply;
216  if ($force) {
217  $reply = 'y';
218  }
219  else {
220  printf( "==> Your copy of 'xref_config.ini' is newer than '%s'\n",
221  catfile( 'sql', 'populate_metadata.sql' ) );
222  print(
223  "==> Should I re-run 'xref_config2sql.pl' for you? [y/N]: ");
224 
225  $reply = <ARGV>;
226  chomp $reply;
227  }
228  if ( lc( substr( $reply, 0, 1 ) ) eq 'y' ) {
229  my $cmd = sprintf( "perl %s %s %u >%s",
230  catfile( $sql_dir, 'xref_config2sql.pl' ),
231  $ini_file, $preparse, $metadata_file );
232 
233  if ( system($cmd) == 0 ) {
234  print("==> Done.\n") if ( $self->verbose );
235  }
236  else {
237  if ( $? == -1 ) {
238  croak("Failed to execute: $!\n");
239  }
240  elsif ( $? & 127 ) {
241  croak( sprintf( "Command died with signal %d, %s coredump\n",
242  ( $? & 127 ),
243  ( $? & 128 ) ? 'with' : 'without' ) );
244  }
245  else {
246  croak( sprintf( "Command exited with value %d\n", $? >> 8 ) );
247  }
248  }
249 
250  }
251  } ## end if ( !defined($meta_tm...))
252  return $metadata_file;
253 } ## end sub prepare_metadata_file
254 
255 sub recreate_database {
256  my ( $self, $force, $drop_db ) = @_;
257  my $user = $self->user;
258  my $dbname = $self->dbname;
259  my $host = $self->host;
260  my $pass = $self->pass;
261  my $port = $self->port;
262  my $dbh = DBI->connect( "DBI:mysql:host=$host:port=$port",
263  $user, $pass, { 'RaiseError' => 1 } );
264  # check to see if the database already exists
265  my %dbs = map { $_->[0] => 1 }
266  @{ $dbh->selectall_arrayref('SHOW DATABASES') };
267 
268  if ( $dbs{$dbname} ) {
269 
270  if ($drop_db) {
271  $dbh->do("DROP DATABASE $dbname");
272  print "Database $dbname dropped\n" if ( $self->verbose );
273  }
274  else {
275 
276  my $p;
277  if ($force) {
278  $p = 'yes';
279  }
280  else {
281  print
282 "WARNING: about to drop database $dbname on $host:$port; yes to confirm, otherwise exit: ";
283  $p = <ARGV>;
284  }
285  chomp $p;
286  if ( $p eq 'yes' ) {
287  $dbh->do("DROP DATABASE $dbname");
288  print "Removed existing database $dbname\n"
289  if ( $self->verbose );
290  }
291  else {
292  print "$dbname NOT removed\n";
293  exit(1);
294  }
295 
296  }
297  } ## end if ( $dbs{$dbname} )
298 
299  $dbh->do( 'CREATE DATABASE ' . $dbname );
300 } ## end sub recreate_database
301 
302 sub populate_with_file {
303  my ( $self, $sql_file ) = @_;
304  my $previous_input_record_separator = $INPUT_RECORD_SEPARATOR;
305  $INPUT_RECORD_SEPARATOR = ";";
306  open( my $sql_fh, "<", $sql_file ) or die $sql_file;
307  while (<$sql_fh>) {
308  s/#(.*?)\n//g;
309  next if /^\s+$/;
310  $self->dbc->do($_);
311  }
312  $INPUT_RECORD_SEPARATOR = $previous_input_record_separator;
313 }
314 
315 1;
map
public map()
Bio::EnsEMBL::DBSQL::DBConnection
Definition: DBConnection.pm:42