diff --git a/Makefile.PL b/Makefile.PL index 2ab0438..c9a2e3e 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -4,9 +4,9 @@ WriteMakefile( NAME => 'pshell', VERSION_FROM => 'lib/History/SQLite.pm', PREREQ_PM => { - 'DBI' => 0, - 'DBD::SQLite' => 0, - 'Term::ReadLine' => 0, - 'Cwd' => 0, + 'DBI' => 0, + 'DBD::SQLite' => 0, + 'Term::ReadLine' => 0, + 'Cwd' => 0, }, ); diff --git a/lib/Environment/SQLite.pm b/lib/Environment/SQLite.pm new file mode 100644 index 0000000..3140930 --- /dev/null +++ b/lib/Environment/SQLite.pm @@ -0,0 +1,79 @@ +package Environment::SQLite; + +use DBI; +use Cwd; + +sub new { + my ($class, %args) = @_; + + my $self = bless { + db_path => $args{db_path} || 'pshell_env.db' + }, $class; + + # Convert to absolute path + $self->{db_path} = getcwd() . '/' . $self->{db_path} unless $self->{db_path} =~ m|^/|; + + $self->_init_db; + + return $self; +} + +sub _init_db { + my ($self) = @_; + + my $dbh = DBI->connect("dbi:SQLite:dbname=$self->{db_path}", "", "", + { RaiseError => 1, PrintError => 0 }); + + $dbh->do(<<"SQL"); + CREATE TABLE IF NOT EXISTS environment ( + name TEXT PRIMARY KEY, + value TEXT NOT NULL + ) +SQL + + $dbh->disconnect; +} + +sub set { + my ($self, $name, $value) = @_; + + my $dbh = DBI->connect("dbi:SQLite:dbname=$self->{db_path}", "", "", + { RaiseError => 1, PrintError => 0 }); + + $dbh->do("REPLACE INTO environment (name, value) VALUES (?, ?)", undef, $name, $value); + + $dbh->disconnect; +} + +sub get { + my ($self, $name) = @_; + + my $dbh = DBI->connect("dbi:SQLite:dbname=$self->{db_path}", "", "", + { RaiseError => 1, PrintError => 0 }); + + my ($value) = $dbh->selectrow_array( + "SELECT value FROM environment WHERE name = ?", undef, $name); + + $dbh->disconnect; + return $value; +} + +sub get_all { + my ($self) = @_; + + my $dbh = DBI->connect("dbi:SQLite:dbname=$self->{db_path}", "", "", + { RaiseError => 1, PrintError => 0 }); + + my $sth = $dbh->prepare("SELECT name, value FROM environment"); + $sth->execute; + + my %env; + while (my $row = $sth->fetchrow_arrayref) { + $env{$row->[0]} = $row->[1]; + } + + $dbh->disconnect; + return %env; +} + +1; diff --git a/pshell.pl b/pshell.pl index 8d91546..d126c38 100755 --- a/pshell.pl +++ b/pshell.pl @@ -2,13 +2,17 @@ use lib 'lib'; use History::SQLite; +use Environment::SQLite; use Term::ReadLine; use Cwd; -# Initialize command history +# Initialize command history and environment my $history = History::SQLite->new( db_path => 'pshell_history.db' ); +my $env = Environment::SQLite->new( + db_path => 'pshell_env.db' +); print "Perl Shell (pshell) - Type 'exit' to quit\n"; @@ -19,6 +23,10 @@ $term->ornaments(0); my @history = $history->get_all; $term->addhistory($_) for @history; +# Load environment variables +my %env_vars = $env->get_all; +$ENV{$_} = $env_vars{$_} for keys %env_vars; + while (1) { my $cwd = getcwd(); my $prompt = "pshell:$cwd> "; @@ -38,6 +46,19 @@ while (1) { next; } + # Handle environment variable assignment + if ($command =~ /^export\s+(\w+)=(.*)/) { + $ENV{$1} = $2; + $env->set($1, $2); + next; + } + + # Handle environment variable display + if ($command eq 'env') { + print "$_=$ENV{$_}\n" for sort keys %ENV; + next; + } + # Save command to history $history->add($command); $term->addhistory($command); diff --git a/pshell_env.db b/pshell_env.db new file mode 100644 index 0000000..e57dab3 Binary files /dev/null and b/pshell_env.db differ