8 John Binns <zombieite@gmail.com>
12 Functions which do basic selects and inserts in a clean way, so your code is easier to read, and SQL is segregated here.
16 my $sql=CXGN::DB::SQLWrappers->new($dbh);
20 Sets verbosity level. Default is 1 meaning loud, setting this to 0 means quiet.
26 A simple way to get primary keys of data which matches some equality conditions. Send in undef for rows you want to match with nulls.
28 my @ids=$sql->select('enzymes',{enzyme_name=>'EcoRI'});
29 #Returns a list of all entries in the enzymes table matching the hash
33 A simple way to insert data into a table.
35 my $id=$sql->insert('enzymes',{enzyme_name=>'NewEnzyme'});
36 #Returns the ID of a new entry into the enzymes table
38 =head2 insert_unless_exists
40 Does a 'select' as described above. If no results are found, does an 'insert' as described above and returns you the ID in a hash. If one result is found, returns you the ID in a hash. If more than one result is found, it dies with a good explanation.
42 my $info=$sql->insert_unless_exists('enzymes',{enzyme_name=>'NewEnzyme'});
45 print"Inserted with ID $info->{id}.\n";
49 print"Similar row exists with ID $info->{id}.\n";
52 =head2 primary_key_column_name
54 Used by this module, but can be used by anyone else that is interested as well. It queries the Postgres catalog database for a single-column primary key associated with a table and dies if it can't find one.
56 my $pk_colname=$sql->primary_key_column_name('enzymes');
62 use CXGN
::DB
::Connection
;
63 use CXGN
::Tools
::Text
;
66 package CXGN
::DB
::SQLWrappers
;
72 my $self=bless({},$class);
81 ($self->{verbose
})=@_;
87 $self->_check_input(@_);
88 my ($table,$select_hash)=@_;
89 my $primary_key_column_name=$self->primary_key_column_name($table);
93 $primary_key_column_name
99 (".join(',',keys(%{$select_hash})).") is distinct from (".join(',',map {'?'} keys(%{$select_hash})).")
101 ";#the "not is distinct from" stuff means "is equal to"--BUT it also works for null values (rather than having to replace "=null" with "is null")
102 my $q=$self->{dbh
}->prepare($select_statement);
103 $q->execute(values(%{$select_hash}));
105 while(my($id)=$q->fetchrow_array())
115 $self->_check_input(@_);
116 my ($table,$insert_hash)=@_;
117 my $insert_statement=
119 insert into sgn.$table
121 join(',',keys(%{$insert_hash}))
125 join(',',map {'?'} keys(%{$insert_hash}))
129 my $q=$self->{dbh
}->prepare($insert_statement);
130 $q->execute(values(%{$insert_hash}));
131 my @row = $q->fetchrow_array();
135 # print STDERR "Executed\n$insert_statement;\nwith values\n(".CXGN::Tools::Text::list_to_string(values(%{$insert_hash})).")\ncreating new row with ID $id.\n\n";
140 sub insert_unless_exists
143 my ($table,$hash)=@_;
145 $return_info->{table
}=$table;
146 my @ids=$self->select($table,$hash);
151 die"insert_unless_exists found more than one existing entry like this (".CXGN
::Tools
::Text
::list_to_string
(@ids)."). This could mean one of 4 things:\n\n1. This table should have a uniqueness constraint, but doesn't\n2. This table has a uniqueness constraint, but null values are causing duplicate rows to appear anyway\n (nulls do NOT match each other in a comparison of rows for the purposes of a uniqueness constraint)\n3: The row you are trying to insert does not specify enough columns of data to differentiate it from similar rows\n4: You meant to use 'insert' instead of 'insert_unless_exists'\n\nHere is what you tried to insert:\n".Data
::Dumper
::Dumper
$hash;
153 $return_info->{exists}=1;
154 ($return_info->{id
})=@ids;
158 $return_info->{inserted
}=1;
159 $return_info->{id
}=$self->insert($table,$hash);
164 sub primary_key_column_name
168 unless($table=~/^\w+$/){die"Invalid table name '$table'"};
169 #this query is a modified version of the one in CXGN::DB::Connection::last_insert_id()
170 my $q=$self->{dbh
}->prepare
181 AND pg_attribute.attrelid=pg_class.oid
182 AND pg_attrdef.adnum=pg_attribute.attnum
183 AND pg_attrdef.adrelid=pg_class.oid
184 AND pg_constraint.conrelid=pg_class.oid
185 AND pg_constraint.contype='p'
186 AND array_upper(pg_constraint.conkey,1)=1
187 AND pg_constraint.conkey[1]=pg_attribute.attnum
188 AND pg_class.relname=?
191 my($primary_key_column_name)=$q->fetchrow_array();
192 unless($primary_key_column_name)
194 die"Primary key column name not found";
196 unless($primary_key_column_name=~/^\w+$/)
198 die"Invalid primary key name found";
200 return $primary_key_column_name;
206 my ($table,$hash)=@_;
207 unless($table=~/^\w+$/)
209 die"Invalid table name '$table'"
211 unless(ref($hash) eq 'HASH')
213 die"Invalid hash '$hash'";
215 for my $key(keys(%{$hash}))
217 unless($key=~/^\w+$/)
219 die"Invalid database column name '$key'";