diff --git a/lib/Redmine/DB/MySQL.pm b/lib/Redmine/DB/MySQL.pm
index ca7c36794a6befeabe9def8cbd63086de8f65028..e75024324f5c032f806d77e903bd8d6927538caa 100644
--- a/lib/Redmine/DB/MySQL.pm
+++ b/lib/Redmine/DB/MySQL.pm
@@ -22,10 +22,13 @@ sub connect
   my $dbh= $self->{'_dbh'};
   return $dbh if (defined ($dbh));
 
-  my $db_con= join (':', 'dbi', map { $self->{$_} } qw(adapter database host));
-  print "db_con=[$db_con]\n";
+  my $adapter= $self->{adapter};
+  $adapter= 'mysql' if ($adapter eq 'mysql2');
+
+  my $db_con= join (':', 'dbi', $adapter, map { $self->{$_} } qw(database host));
+  # print "db_con=[$db_con]\n";
   $dbh= DBI->connect($db_con, map { $self->{$_} } qw(username password));
-  print "dbh=[$dbh]\n";
+  # print "dbh=[$dbh]\n";
   $self->{'_dbh'}= $dbh;
 }
 
@@ -40,7 +43,7 @@ sub table
   $t;
 }
 
-=head2 $con->get_all_x ($table_name, $query_ref)
+=head2 $con->get_all_x ($table_name, $query_ref, $field_ref)
 
 Query_ref is an array reference where the first parameter gives the WHERE clause (without the string "WHERE").
 The query should not contain untrustable values, these should be indicated by placeholders (an "?" for each
@@ -57,6 +60,7 @@ sub get_all_x
   my $self= shift;
   my $table= shift;
   my $where= shift;
+  my $field_ref= shift || '*';
 
   my $dbh= $self->connect();
   return undef unless (defined ($dbh));
@@ -64,7 +68,7 @@ sub get_all_x
   # my $project= new Redmine::DB::Project (%par);
   # print "project: ", Dumper ($project);
 
-  my $ss= "SELECT * FROM $table";
+  my $ss= "SELECT $field_ref FROM $table";
 
   my @v= ();
   if (defined ($where))
@@ -88,16 +92,101 @@ sub get_all_x
   my $t= $self->table($table);
   my $tt= {};
 
+  my $pri= (exists ($self->{PRI}->{$table})) ? $self->{PRI}->{$table} : 'id';
   while (defined (my $x= $sth->fetchrow_hashref()))
   {
     print "x: ", Dumper ($x) if ($show_fetched);
-    my $i= $x->{'id'};
+    my $i= $x->{$pri};
     $t->{$i}= $tt->{$i}= $x;
   }
 
   $tt;
 }
 
+sub tables
+{
+  my $self= shift;
+
+  my $dbh= $self->connect();
+  return undef unless (defined ($dbh));
+
+  my $ss= "SHOW TABLES";
+
+  if ($show_query)
+  {
+    print "ss=[$ss]\n";
+  }
+
+  my $sth= $dbh->prepare($ss) or print $dbh->errstr;
+  # print "sth=[$sth]\n";
+  $sth->execute();
+
+  my $table_filter= $self->{table_filter};
+
+  my $table_names= $self->{table_names}= {};
+  while (defined (my $table_name= $sth->fetchrow_array()))
+  {
+    next if (defined ($table_filter) && &$table_filter($table_name) == 0);
+    $table_names->{$table_name}= undef;
+  }
+
+  $table_names;
+}
+
+sub desc_all
+{
+  my $self= shift;
+
+  my $table_names= $self->tables();
+
+  foreach my $table_name (sort keys %$table_names)
+  {
+    $self->desc($table_name);
+  }
+}
+
+sub desc
+{
+  my $self= shift;
+  my $table= shift;
+
+  my $dbh= $self->connect();
+  return undef unless (defined ($dbh));
+
+  my $ss= "DESC `$table`";
+
+  if ($show_query)
+  {
+    print "ss=[$ss]\n";
+  }
+
+  my $sth= $dbh->prepare($ss) or print $dbh->errstr;
+  # print "sth=[$sth]\n";
+  $sth->execute();
+
+  # get table definition
+  my $td= $self->{table_names}->{$table};
+  my $td= $self->{table_names}->{$table}= {} unless (defined ($td));
+  my $tt= $td->{'columns'}= [];
+
+  # my @desc_columns= qw(Field Type Null Key Default Extra);
+
+  while (defined (my @x= $sth->fetchrow_array()))
+  {
+    last unless (@x);
+    # print "x: ", Dumper (\@x); # if ($show_fetched);
+    push (@$tt, \@x);
+
+    if ($x[3] eq 'PRI')
+    {
+      $self->{PRI}->{$table}= $x[0];
+    }
+  }
+
+  $td;
+}
+
+# BEGIN Redmine specific part
 sub fetch_custom
 {
   my $db= shift;
diff --git a/t_sync.pl b/t_sync.pl
index cd244c7d0288c260d5bd3b434488494bb459b615..d9213c725da83eb7871f70930de47494b3f0892a 100755
--- a/t_sync.pl
+++ b/t_sync.pl
@@ -300,7 +300,7 @@ sub read_configs
   # $ss->{'_cfg'}=
   my $c= $x->{$db};
 
-  $c->{'adapter'}= 'mysql' if ($c->{'adapter'} eq 'mysql2');
+  # $c->{'adapter'}= 'mysql' if ($c->{'adapter'} eq 'mysql2');
   my $m= new Redmine::DB::MySQL (%$c);
 
   $ss->{'m'}= $m;