PageRenderTime 62ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/CXGN/Map/Version.pm

https://github.com/solgenomics/cxgn-corelibs
Perl | 258 lines | 181 code | 45 blank | 32 comment | 23 complexity | 6b5d1eb883f697ba80643e263352e7d1 MD5 | raw file
  1. =head1 NAME
  2. CXGN::Map::Version
  3. =head1 AUTHOR
  4. John Binns <zombieite@gmail.com>
  5. =head1 DESCRIPTION
  6. Object for creating a new map version.
  7. =head2
  8. new
  9. #simple example (uses linkage group names from previous current version of this map)
  10. my $new_map_version=CXGN::Map::Version->new($dbh,{map_id=>$map_id});
  11. #example where you want to base a new map_version on an old on (which in not necessarily a current one)
  12. my $new_map_version=CXGN::Map::Version->new($dbh,{map_version_id=>$map_version_id});
  13. #example where you have new linkage group names to define, because they have changed since the previous version.
  14. #linkage group order matters, and is taken from the order of the linkage group names in the list.
  15. my $linkage_groups=['1','2','3','4','5','6','7a','7b','8','9','10','11','12'];
  16. my $new_map_version=CXGN::Map::Version->new($dbh,{map_id=>$map_id},$linkage_groups);
  17. =head2
  18. insert_into_database
  19. #note: this WILL INSERT data into the database... EVERY time you call it!
  20. #it is not like some of my other modules which do a "store_unless_exists".
  21. #calling it, say, 5 times, will store 5 new map versions (it was simpler
  22. #to write this way). if you have created this map version from an existing
  23. #map_version, this function will return a NEW map_version_id for the NEW
  24. #row that you have inserted.
  25. my $new_map_version_id=$new_map_version->insert_into_database();
  26. =head2
  27. set_current
  28. #how to make an existing map_version current
  29. my $existing_map_version=CXGN::Map::Version->new($dbh,{map_version_id=>$map_version_id});
  30. $existing_map_version->set_current();
  31. =cut
  32. use strict;
  33. use CXGN::DB::Connection;
  34. use CXGN::Map;
  35. use CXGN::Tools::Text;
  36. package CXGN::Map::Version;
  37. sub new {
  38. my $class = shift;
  39. my($dbh,$map_info,$linkage_groups) = @_;
  40. my $self = bless({},$class);
  41. CXGN::DB::Connection::is_valid_dbh($dbh)
  42. or die "You must supply a dbh as the first argument";
  43. $self->{dbh} = $dbh;
  44. #just a test to make sure our map_id is valid
  45. unless (CXGN::Map->new($dbh,$map_info)) {
  46. die "Cannot create a map object, so this map ID or map_version_id "
  47. # . "--\n\n".Dumper $map_info."\n\n-- "
  48. . "is probably invalid";
  49. }
  50. $self->{map_id} = $map_info->{map_id};
  51. $self->{map_version_id} = $map_info->{map_version_id};
  52. # if the caller has specified a map_version_id,
  53. # why would they also specify the linkage groups?
  54. # shouldn't they just specify a map_id and linkage groups instead?
  55. # i don't think they know what they're doing.
  56. if ($self->{map_version_id} and $linkage_groups) {
  57. die "If you're specifying the linkage groups manually,"
  58. . "there's no reason to import them by specifying a "
  59. . "map_version_id. Specify a map_id and linkage groups instead.";
  60. }
  61. #if the caller is sending in linkage group names, use them
  62. if ($linkage_groups) {
  63. if (@{$linkage_groups}) {
  64. for my $lg_name(@{$linkage_groups}) {
  65. # one digit, optionally followed by another, optionally followed
  66. # by a lowercase letter--modify this regex if needed
  67. # unless ($lg_name=~/^\d\d?(\.\d|[a-z]?)$/) {
  68. # die "'$lg_name' is not a valid linkage group name";
  69. # }
  70. }
  71. $self->{linkage_groups}=$linkage_groups;
  72. }
  73. else { die "No linkage groups found" }
  74. }
  75. # otherwise, use the linkage group names from the previous current version of this map
  76. else {
  77. my $sth;
  78. if ($self->{map_id}) {
  79. my $select = "select lg_name,lg_order from map_version inner "
  80. . "join linkage_group using (map_version_id) where "
  81. . "current_version and map_id=? order by lg_order";
  82. $sth = $dbh->prepare($select);
  83. $sth->execute($self->{map_id});
  84. }
  85. elsif ($self->{map_version_id}) {
  86. my $select = "select map_id from map_version where map_version_id=?";
  87. $sth = $dbh->prepare($select);
  88. $sth->execute($self->{map_version_id});
  89. ($self->{map_id}) = $sth->fetchrow_array();
  90. $self->{map_id} or die "Could not find map_id from map_version_id";
  91. $select = "select lg_name,lg_order from map_version inner "
  92. . "join linkage_group using (map_version_id) where "
  93. . "map_version_id=? order by lg_order";
  94. $sth=$dbh->prepare($select);
  95. $sth->execute($self->{map_version_id});
  96. }
  97. else {
  98. die "Oops, I seem to have no map_id or map_version_id "
  99. . "to base this new map version on";
  100. }
  101. while (my($lg_name)=$sth->fetchrow_array()) {
  102. push(@{$self->{linkage_groups}},$lg_name);
  103. }
  104. }
  105. return $self;
  106. }
  107. #call this any old time, for debugging or informational purposes
  108. sub as_string {
  109. my $self = shift;
  110. if ($self->{map_version_id}) {
  111. print "Map version ID: $self->{map_version_id}\n";
  112. }
  113. else {
  114. print "This object has no map_version_id.\nIt was not "
  115. . "created from an existing map_version,\nand it has "
  116. . "not yet been inserted into the database.\n";
  117. }
  118. print "Map ID: $self->{map_id}\n";
  119. print "Linkage group names (in order):\n";
  120. my @lgs = @{$self->{linkage_groups}};
  121. for my $lg(@lgs) {
  122. print "$lg\n";
  123. }
  124. }
  125. # note that this is NOT a "store_unless_exists"-type function.
  126. # this method WILL INSERT a new map version in the database--EVERY time you call it!
  127. sub insert_into_database {
  128. my $self = shift;
  129. my $dbh = $self->{dbh};
  130. my $insert = "insert into sgn.map_version (map_id,date_loaded) values (?,current_timestamp) RETURNING map_version_id";
  131. my $sth = $dbh->prepare($insert);
  132. $sth->execute($self->{map_id});
  133. if (my @row =$sth->fetchrow_array()) {
  134. $self->{map_version_id} = $row[0];
  135. } else {
  136. die "Could not insert map_version\n";
  137. }
  138. # the other lg_order values currently in the db start with 1,
  139. # so i'm keeping this convention. it doesn't really matter
  140. # too much, since the only time lg_order is used (as far as i know)
  141. # is in an "order by" clause, which doesn't care what number you start with.
  142. my $lg_order=1;
  143. for my $lg_name (@{$self->{linkage_groups}}) {
  144. $insert = "insert into sgn.linkage_group "
  145. . "(lg_name,lg_order,map_version_id) values (?,?,?)";
  146. my $sth = $dbh->prepare($insert);
  147. $sth->execute($lg_name,$lg_order,$self->{map_version_id});
  148. $lg_order++;
  149. }
  150. return $self->{map_version_id};
  151. }
  152. #this sets all other versions of the map to be not current and sets this one to be current
  153. sub set_current {
  154. my $self = shift;
  155. my $dbh = $self->{dbh};
  156. $self->{map_id}
  157. or die "I can't set the other versions to be not current without knowing our map_id";
  158. $self->{map_version_id}
  159. or die "I can't set myself to be current without knowing "
  160. . "what my map_version_id is--insert me into the database first";
  161. my $update = "update map_version set current_version='f' where map_id=?";
  162. my $sth = $dbh->prepare($update);
  163. $sth->execute($self->{map_id});
  164. $update = "update map_version set current_version='t' where map_version_id=?";
  165. $sth=$dbh->prepare($update);
  166. $sth->execute($self->{map_version_id});
  167. }
  168. sub map_version {
  169. my $self = shift;
  170. my $dbh = shift;
  171. my $map_id = shift;
  172. print STDERR "mapid from map_version func: $map_id\n";
  173. my ($map_version_id_old, $map_version_id_new, $sth);
  174. if ($map_id) {
  175. $sth = $dbh->prepare("SELECT map_version_id
  176. FROM sgn.map_version
  177. WHERE map_id =?");
  178. $sth->execute($map_id);
  179. $map_version_id_old = $sth->fetchrow_array();
  180. $sth = $dbh->prepare("INSERT INTO sgn.map_version (map_id, date_loaded)
  181. VALUES (?, current_timestamp) RETURNING map_version_id"
  182. );
  183. $sth->execute($map_id);
  184. if (my @row = $sth->fetchrow_array()) {
  185. $map_version_id_new = $row[0];
  186. print STDERR "stored new map version id: $map_version_id_new\n";
  187. } else {
  188. die("Error could not insert new map_version $map_id\n");
  189. }
  190. } else { die "map_version function: I need a map id to create map version\n";}
  191. if ($map_version_id_old) {
  192. my $sth = $dbh->prepare("UPDATE map_version
  193. SET current_version='f'
  194. WHERE map_version_id=?"
  195. );
  196. $sth->execute($map_version_id_old);
  197. }
  198. if($map_version_id_new) {
  199. $sth=$dbh->prepare("UPDATE map_version
  200. SET current_version='t'
  201. WHERE map_version_id=?"
  202. );
  203. $sth->execute($map_version_id_new);
  204. } else {die "I can't set myself to be current without knowing "
  205. . "what my map_version_id is--insert me into the database first";
  206. }
  207. return $map_version_id_new;
  208. }
  209. 1;