package Bucky::DB; use base 'Bucky'; use Data::Dumper; use DBI; my $DB_LOOKUP = { bucky => '', user => 'users', keyword => 'keywords', thread => 'threads', file => 'files', comment => 'comments', family => 'family', search_log => 'search_log', poetaster_log => 'poetaster_log', svn => 'svn', }; sub insert { my ($self, $type, $record) = @_; $type = $DB_LOOKUP->{$type}; return unless $type && ref($record) eq "HASH" && scalar keys %$record; my $keys = []; my $values = []; foreach my $key (keys %$record) { push @$keys, $key; push @$values, $self->quote($record->{$key}); } my $key_string = join ",", @$keys; my $value_string = join ",", @$values; return unless length $key_string && length $value_string; my $sql = "INSERT INTO $type ($key_string) VALUES($value_string)"; $self->execute($sql); return $self->lastinsertid($sql); } sub update { my ($self, $type, $opt) = @_; my $criteria = $opt->{'criteria'}; my $record = $opt->{'record'}; $type = $DB_LOOKUP->{$type}; return unless $type && ref($record) eq "HASH" && scalar keys %$record; my $key_values = []; foreach my $key (keys %$record) { push @$key_values, $key . "=" . $self->quote($record->{$key}); } my $key_value_string = join ",", @$key_values; return unless length $key_value_string; my $criteria_string = $self->criteria($criteria); return unless length $criteria_string; my $sql = "UPDATE $type SET $key_value_string $criteria_string"; $self->execute($sql); } sub update_by_id { my ($self, $type, $opt) = @_; my $id = $opt->{'id'} + 0; $opt->{'criteria'} = "id=$id"; $self->update($type, $opt) } sub select { my ($self, $type, $criteria) = @_; $type = $DB_LOOKUP->{$type}; return unless $type; my $criteria_string = $self->criteria($criteria); my $rows = []; my $sql = "SELECT * FROM $type"; $sql .= " " . $criteria_string if $criteria_string; my $sth = $self->execute($sql); while (my $row = $sth->fetchrow_hashref) { push @$rows, $row; } return $rows; } sub select_by_id { my ($self, $type, $id_array) = @_; $type = $DB_LOOKUP->{$type}; return unless $type and ref($id_array) eq "ARRAY" and scalar @$id_array; my $rows = {}; my $ids = join ",", @$id_array; my $sql = "SELECT * FROM $type"; $sql .= " WHERE id IN ($ids)"; my $sth = $self->execute($sql); while (my $row = $sth->fetchrow_hashref) { $rows->{ $row->{'id'} } = $row; } return $rows; } sub criteria { my ($self, $criteria) = @_; my $criteria_list = []; if ($self->is_string($criteria)) { push @$criteria_list, $criteria; } elsif (ref $criteria eq "HASH") { foreach my $key (keys %$criteria) { my $criterion = $key; if ($criteria->{$key}) { $criterion .= "=" . $self->quote($criteria->{$key}); } push @$criteria_list, $criterion; } } return undef unless scalar @$criteria_list; my $criteria_string = join(" AND ", @$criteria_list); $criteria_string = "WHERE " . $criteria_string if $criteria_string =~ /[=<>]|( (IS|IN) )/; return $criteria_string; } sub execute { my ($self, $sql) = @_; my $sth = $self->dbh->prepare($sql); $sth->execute; return $sth; } sub quote { my ($self, $string) = @_; return $self->dbh->quote($string); } sub lastinsertid { my ($self) = @_; return $self->dbh->last_insert_id(0, undef, undef, undef); } sub dbh { my ($self, $parent) = @_; if ($parent && ref($parent) =~ /Bucky/) { $self->{_dbh} ||= $parent->dbh; } if (! $self->{_dbh}) { $self->{_dbh} ||= DBI->connect($self->dsn); } return $self->{_dbh}; } sub dsn { my ($self) = @_; $self->{_dsn} ||= "DBI:mysql:database=" . $self->db_name . ":" . $self->db_host . ";mysql_read_default_file=" . $self->my_cnf; return $self->{_dsn}; } sub db_name { 'bucky3' } sub db_host { 'localhost' } sub my_cnf { './.my.cnf' } 1;