merge master
[sgn.git] / lib / CXGN / Stock / StockLookup.pm
blobc6a02b29fedc325c700e001f56a7c599b1050f71
1 package CXGN::Stock::StockLookup;
3 =head1 NAME
5 CXGN::Stock::StockLookup - a module to lookup stock names by unique name or synonym.
7 =head1 USAGE
9 my $stock_lookup = CXGN::Stock::StockLookup->new({ schema => $schema} );
12 =head1 DESCRIPTION
14 Looks up stocks ("Stock::Stock") that have a match with the unique name or synonym to the searched name. Provides a count of matching stocks when more than one stock is found. Provides the Stock::Stock object when only a single stock matches.
16 =head1 AUTHORS
18 Jeremy D. Edwards (jde22@cornell.edu)
20 =cut
22 use Moose;
23 use MooseX::FollowPBP;
24 use Moose::Util::TypeConstraints;
25 use Try::Tiny;
26 use SGN::Model::Cvterm;
28 has 'schema' => (
29 is => 'rw',
30 isa => 'DBIx::Class::Schema',
31 lazy_build => 1,
34 =head2 predicate has_stock_name(), clearer clear_stock_name(), accessors stock_name()
36 functions to test, clear, set or get the stock name.
38 =cut
40 has 'stock_name' => (isa => 'Str', is => 'rw', predicate => 'has_stock_name', clearer => 'clear_stock_name');
42 =head2 get_stock
44 Usage: $self-> get_stock($stock_type_id, $stock_organism_id)
45 Desc: check if the uniquename exists in the stock table
46 Ret: stock object_row
47 Args: optional: stock_type_id (cvterm_id) , $stock_organism_id (organism_id)
48 Side Effects: calls _get_stock_resultset, returns only one object row even if multiple stocks are found (would happen only if there are multiple stocks with the same uniquename of different letter case or different type_id or different organism_id)
49 Example: $self->get_stock(undef, $manihot_esculenta_organism_id)
51 =cut
53 sub get_stock {
54 my $self = shift;
55 my $stock_type_id = shift;
56 my $stock_organism_id = shift;
57 my $stock_rs = $self->_get_stock_resultset($stock_type_id, $stock_organism_id);
58 my $stock;
59 if ($stock_rs->count > 0) {
60 $stock = $stock_rs->first;
61 } else {
62 return;
64 return $stock;
67 =head2 function get_stock_exact()
69 retrieves the stock row with an exact match to the stock name or synonym
71 =cut
73 sub get_stock_exact {
74 my $self = shift;
75 my $stock_rs = $self->_get_stock_resultset_exact();
76 my $stock;
77 if ($stock_rs->count == 1) {
78 $stock = $stock_rs->first;
79 } else {
80 return;
82 return $stock;
85 =head2 function get_matching_stock_count()
87 retrieves the number of stocks that match the name (or synonym)
89 =cut
91 sub get_matching_stock_count {
92 my $self = shift;
93 my $stock_name = $self->get_stock_name();
94 my $stock_rs = $self->_get_stock_resultset();
95 if (!$stock_rs) {
96 return;
98 my $stock_match_count = $stock_rs->count;
99 if (!$stock_match_count) {
100 return 0;
102 if ($stock_match_count == 0) {
103 return;
105 return $stock_match_count;
108 sub get_synonym_hash_lookup {
109 my $self = shift;
110 print STDERR "Synonym Start:".localtime."\n";
111 my $schema = $self->get_schema();
112 my $synonym_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'stock_synonym', 'stock_property')->cvterm_id();
113 my $accession_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'accession', 'stock_type')->cvterm_id();
114 my $q = "SELECT stock.uniquename, stockprop.value FROM stock JOIN stockprop USING(stock_id) WHERE stock.type_id=$accession_type_id AND stockprop.type_id=$synonym_type_id ORDER BY stockprop.value;";
115 my $h = $schema->storage->dbh()->prepare($q);
116 $h->execute();
117 my %result;
118 while (my ($uniquename, $synonym) = $h->fetchrow_array()) {
119 push @{$result{$uniquename}}, $synonym;
121 print STDERR "Synonym End:".localtime."\n";
122 return \%result;
125 sub get_owner_hash_lookup {
126 my $self = shift;
127 my $stock_ids;
128 my $where_clause = '';
129 print STDERR "StockOwner Start:".localtime."\n";
130 if ($stock_ids){
131 my $stock_id_sql = join ',', @$stock_ids;
132 $where_clause = "WHERE stock_id IN ($stock_id_sql)";
134 my $schema = $self->get_schema();
135 my $q = "SELECT stock_id, sp_person_id, username, first_name, last_name FROM sgn_people.sp_person JOIN phenome.stock_owner USING(sp_person_id) $where_clause GROUP BY (stock_id, sp_person_id, username, first_name, last_name) ORDER BY sp_person_id;";
136 my $h = $schema->storage->dbh()->prepare($q);
137 $h->execute();
138 my %result;
139 while (my ($stock_id, $sp_person_id, $username, $first_name, $last_name) = $h->fetchrow_array()) {
140 push @{$result{$stock_id}}, [$sp_person_id, $username, $first_name, $last_name];
142 print STDERR "StockOwner End:".localtime."\n";
143 return \%result;
146 sub get_organization_hash_lookup {
147 my $self = shift;
148 print STDERR "StockOrg Start:".localtime."\n";
149 my $schema = $self->get_schema();
150 my $organization_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'organization', 'stock_property')->cvterm_id();
151 my $q = "SELECT stock_id, value FROM stockprop WHERE type_id=$organization_type_id ORDER BY value;";
152 my $h = $schema->storage->dbh()->prepare($q);
153 $h->execute();
154 my %result;
155 while (my ($stock_id, $organization) = $h->fetchrow_array()) {
156 push @{$result{$stock_id}}, $organization;
158 print STDERR "StockOrg End:".localtime."\n";
159 return \%result;
162 sub _get_stock_resultset {
163 my $self = shift;
164 my $stock_type_id = shift;
165 my $stock_organism_id = shift;
166 my $schema = $self->get_schema();
167 my $stock_name = $self->get_stock_name();
168 my $search_hash = {
169 'me.is_obsolete' => { '!=' => 't' },
170 -or => [
171 'lower(me.uniquename)' => { like => lc($stock_name) },
172 -and => [
173 'lower(type.name)' => { like => '%synonym%' },
174 'lower(stockprops.value)' => { like => lc($stock_name) },
178 if ($stock_type_id){
179 $search_hash->{'me.type_id'} = $stock_type_id;
181 if ($stock_organism_id) {
182 $search_hash->{'me.organism_id'} = $stock_organism_id;
184 my $stock_rs = $schema->resultset("Stock::Stock")
185 ->search($search_hash,
187 join => { 'stockprops' => 'type'} ,
188 distinct => 1
191 return $stock_rs;
194 sub _get_stock_resultset_exact {
195 my $self = shift;
196 my $schema = $self->get_schema();
197 my $stock_name = $self->get_stock_name();
198 my $stock_rs = $schema->resultset("Stock::Stock")
199 ->search({ 'me.is_obsolete' => { '!=' => 't' },
200 'uniquename' => $stock_name,
203 join => { 'stockprops' => 'type'} ,
204 distinct => 1,
207 return $stock_rs;
210 sub get_stock_synonyms {
211 my $self = shift;
212 my $search_type = shift; # 'stock_id' | 'uniquename' | 'any_name'
213 my $stock_type = shift; # type of stock ex 'accession'
214 my $to_get = shift; # array ref
216 my $schema = $self->get_schema();
218 my $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($schema,$stock_type,'stock_type')->cvterm_id;
220 my $table_joins = {
221 join => { 'stockprops' => 'type'},
222 '+select' => ['stockprops.value','type.name'],
223 '+as' => ['stockprop_value','cvterm_name']
224 # join_type => 'FULL_OUTER'
226 my $query = {
227 'me.is_obsolete' => { '!=' => 't' },
228 'me.type_id' => {'=' => $stock_type_id}
230 if ($search_type eq 'stock_id'){
231 $query->{'me.stock_id'} = {-in=>$to_get};
232 } elsif ($search_type eq 'uniquename'){
233 $query->{'me.uniquename'} = {-in=>$to_get};
234 } elsif ($search_type eq 'any_name'){
235 $query->{'-or'} = [
236 'me.uniquename' => {-in=>$to_get},
237 -and => [
238 'type.name' => 'stock_synonym',
239 'stockprops.value' => {-in=>$to_get}
242 } else {
243 die;
245 my $stock_rs = $schema->resultset("Stock::Stock")
246 ->search($query,$table_joins);
247 my $synonym_hash = {};
248 while( my $row = $stock_rs->next) {
249 my $uname = $row->uniquename;
250 if (not defined $synonym_hash->{$uname}){
251 $synonym_hash->{$uname} = [];
253 my $cvname = $row->get_column('cvterm_name');
254 if ($cvname && $cvname eq 'stock_synonym'){
255 push @{$synonym_hash->{$uname}}, $row->get_column('stockprop_value');
258 return $synonym_hash;
261 =head2 function get_cross_exact()
263 retrieves the stock row with cross stock type and with an exact match to the stock name
265 =cut
267 sub get_cross_exact {
268 my $self = shift;
269 my $schema = $self->get_schema();
270 my $stock_name = $self->get_stock_name();
271 my $cross_type_id = SGN::Model::Cvterm->get_cvterm_row($schema,'cross','stock_type')->cvterm_id;
273 my $stock_rs = $schema->resultset("Stock::Stock")->search({ 'me.is_obsolete' => { '!=' => 't' }, 'uniquename' => $stock_name, 'type_id' => $cross_type_id });
274 my $stock;
275 if ($stock_rs->count == 1) {
276 $stock = $stock_rs->first;
277 } else {
278 return;
280 return $stock;
284 =head2 function get_accession_exact()
286 retrieves the stock row with accession stock type and with an exact match to the stock name
288 =cut
290 sub get_accession_exact {
291 my $self = shift;
292 my $schema = $self->get_schema();
293 my $stock_name = $self->get_stock_name();
294 my $accession_type_id = SGN::Model::Cvterm->get_cvterm_row($schema,'accession','stock_type')->cvterm_id;
296 my $stock_rs = $schema->resultset("Stock::Stock")->search({ 'me.is_obsolete' => { '!=' => 't' }, 'uniquename' => $stock_name, 'type_id' => $accession_type_id });
297 my $stock;
298 if ($stock_rs->count == 1) {
299 $stock = $stock_rs->first;
300 } else {
301 return;
303 return $stock;
307 #######
309 #######