PM/Database.pm
2016-05-09 17:01:40 +08:00

207 lines
4.8 KiB
Perl

package Database;
use DBI;
use GPG;
use Term::ANSIColor;
use Password;
sub new {
my $class = shift;
# Get home dir
my $home = $ENV{HOME};
my $gpg = GPG->new($home);
my $self = {
_home => $home,
_gpg => $gpg,
};
bless $self, $class;
return $self;
}
sub connect {
my ( $self, $db_file ) = @_;
my $dbh = DBI->connect( "dbi:SQLite:dbname=$db_file", "", "" );
return $dbh;
}
sub print_table {
my ( $sth ) = @_;
@max = (0, 0, 0, 0, 0, 0);
@rows;
$sum = 2;
@colors = ("white", "magenta", "bold magenta", "blue", "green", "yellow");
while ( my @row = $sth->fetchrow_array() )
{
push(@rows, \@row);
}
@labels = ("ID", "NAME", "GROUP", "RESOURCE", "USERNAME", "COMMENT");
@rows=reverse(@rows);
push(@rows, \@labels);
foreach my $row(@rows) {
for $i (0 .. 5) {
$str = $row -> [$i];
$l=length($str);
if ($l > $max[$i]) {
$max[$i] = $l;
}
}
}
foreach my $num(@max) {
$sum += ($num + 3);
}
while (my $row = pop(@rows)) {
print "-" x $sum . "\n";
for $i (0 .. 5) {
$l=$max[$i];
$string=$row -> [$i];
$strl=$l-length($string);
$color=$colors[$i];
printf "| %s ", colored($string, $color).(' ' x $strl);
}
print " |\n";
}
print "-" x $sum . "\n";
}
# Query proccessing mechanism
sub mdo {
my ( $self, $query ) = @_;
my $db_file = $query->{file};
my $q = $query->{query};
my $name = $query->{name};
my $type = $query->{type};
my $g = $query->{group};
my $dbh = Database->connect($db_file);
# Select
if ( $type eq 'select' ) {
# Bad hack
if ( $name eq 'all' ) {
my $q
= 'select id, name, `group`, resource, username, comment from passwords';
my $sth = $dbh->prepare($q);
my $rv = $sth->execute();
print_table ($sth);
# Remove unencrypted file
my @rm_cmd = ( "rm", "-f", "$db_file" );
system(@rm_cmd) == 0
or die "Cannot remove unencrypted database! $!\n";
exit 0;
}
# Show group
if ($g) {
my $sth = $dbh->prepare($q);
my $rv = $sth->execute();
print_table($sth);
# Remove unencrypted file
my @rm_cmd = ( "rm", "-f", "$db_file" );
system(@rm_cmd) == 0
or die "Cannot remove unencrypted database! $!\n";
exit 0;
}
my $sth = $dbh->prepare($q);
$sth->execute();
my ( $id, $name, $resource, $password ) = $sth->fetchrow_array();
my $q_hash = {
id => $id,
name => $name,
resource => $resource,
password => $password,
};
return $q_hash;
}
elsif ( $type eq 'do' ) {
$dbh->do("$q") or die "$!\n";
return 0;
}
else {
print STDERR "Something went wrong! $!\n";
return 1;
}
return 1;
}
# Create config dirrectory and DB if not exist
sub create_base {
my ($self) = @_;
my $home = $self->{_home};
my $pm_dir = $home . "/.PM/";
my $gpg = $self->{_gpg};
# Check dir
if ( !( -d $pm_dir ) or !( -e $pm_dir . "db.sqlite" ) ) {
# Remove old configuration dirrectory
print "Remove old dirrectory...\n";
my @rm_old_cmd = ( 'rm', '-rf', $pm_dir );
system(@rm_old_cmd) == 0 or die "Cannot remove $pm_dir: $!\n";
# Create dirrectory
print "Creating configuration dirrectory...\n";
my @mkdir_cmd = ( "mkdir", "$pm_dir" );
system(@mkdir_cmd) == 0 or die "Cannot create dir $pm_dir: $!\n";
my $pass = Password->new();
my $string = $pass->generate();
my $first_sqlite = "/tmp/$string";
# Create DB file
my @createdb_cmd = ( "touch", "$first_sqlite" );
system(@createdb_cmd) == 0 or die "Cannot create database file: $!\n";
print "Creating database...\n";
# Create table.
my $dbh = DBI->connect( "dbi:SQLite:dbname=$first_sqlite", "", "" );
print "Create database schema\n";
my $q_table
= "CREATE TABLE passwords(
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name VARCHAR(32) NOT NULL,
username VARCHAR(32) NOT NULL,
resource TEXT NOT NULL,
password VARCHAR(32) NOT NULL,
comment TEXT NOT NULL,
'group' VARCHAR(32) NOT NULL
)";
$dbh->do($q_table);
print "Encrypt database...\n";
# Encrypt db
$gpg->encrypt_db($first_sqlite);
return 0;
}
else {
print "Dirrectory is exist!\n";
return 1;
}
return 1;
}
1;