Sprite.pm development, comments and bug report page
Sprite is a Perl 5 module that implements a subset of SQL-92 to manipulate text-delimited
databases.
If you want to contribute to Sprite development, contact me
(rodrigo @ insite.com.br).
Sprite was originally developed by Shishir Gundavaram (shishir @ ora.com).
(this page is maintained by Rodrigo Siqueira - june/1998)
1. I've created:
sprite.pl - shell sql interface for Sprite.
DBD::Sprite - DBD/DBI driver to access Sprite database.
-------------------------------------------------------------------------------
2. 'sub select' has been altered from the original module:
* Included "ORDER BY column [DESC]" in the select statement.
* Included "LIMIT offset,length" statement.
my ($order_by, $sort_order)
($columns, $table, $extra) = ($1, $2, $3);
if ($extra =~ s/\s+order\s+by\s+(.+)$//i) {
$order_by = $1;
(...)
if ($order_by) {
if ($order_by =~ s/\s+desc$//i) {
$sort_order = -1;
} else {
$sort_order = 1;
}
my @columns = split (/$self->{_read}/o, $columns);
my $col_number=0;
foreach (@columns) {
last if ($_ eq $order_by);
$col_number++;
}
if ($col_number>$#columns) { # Order by: Column not found
return (-502);
}
if ($sort_order == 1) {
@$values_or_error = sort {
@$a[$col_number] <=> @$b[$col_number]
or @$a[$col_number] cmp @$b[$col_number]
} @$values_or_error;
} else {
@$values_or_error = sort {
@$b[$col_number] <=> @$a[$col_number]
or @$b[$col_number] cmp @$a[$col_number]
} @$values_or_error;
}
}
return $values_or_error;
------------------------------------------------------------------------
3. When I need to get field names from a database, I used this:
$fields = $rdb->{fields};
print join (',', keys %$fields);
But it should be better to be able to get column names in the right
order when a select is made.
I included inside the sub select the following:
$self->{NAME} = [ split(/,/, $columns) ];
(include this after the $values_or_error = $self->parse_columns... line)
Now it's easy to retrieve the column names and it seems much like DBI:
print "First column name: $rdb->{NAME}->[0]\n";
In the future, column names could also be retrieved as a sql statement,
something like 'SHOW FIELDS FROM database' (or 'SHOW COLUMNS FROM database')
-----------------------------------------------------------------------
4. The 'sub sql' has been changed from the original module:
* Included better error handling funcion:
There was no way to find what kind of error happened in a query,
the only way was looking the STDERR output. Perl scripts that use Sprite
should be able to know and display the errors.
Correction: 'sub sql' should not only return 0 or 1 (or the array reference
in case of 'select'), but also set the error, it it has one. After the
"if ($status <= 0)" I included the following line:
$self->{error} = $self->{errors}->{$status};
With this, it would be very easy to get the error with the Perl script.
It's just:
print $rdb->{error};
The "return (-514) unless ($query)" line in the beginning of this 'sub sql'
seems also not to be ok, because this sub should return 0 or 1.
------------------------------------------------------------------------
BUG 1:
When the database is empty (only column names are specified),
the 'close' method fails because of the check method in line 1015
(will return error 513 saying that the database was not opened)
BUG 2:
This is working: 'select * from database'
This is not working: 'select * from database'
BUG 3:
Two restrictions using '=' does not works.
OK: select * from test where ID = "1"
NOT OK: select * from test where ID = "1" and NAME = "insite.com.br"
BUG 4:
There is a regexp bug around the parse line:
$query =~ s/([!=]~)\s*(m)?([^\w;\s])([^\3\\]*(?:\\.[^\3\\]*)*)\3(i)?/
Our local regexp guru has corrected, and I'll inform more and send
details later.
BUG 5:
"sub set_os" does not identify correctly OS name.
The regex is:
$platform =~ /^(?:OS2|(?:Win)?NT|Win(?:dows)?95|(?:MS)?DOS)$/i
My $^O says "MSWin32", that does not match this regex.
Correction: Just remove the '^' and the '95' from it.
BUG 6:
If for some reason "Sprite.lck" is not deleted after the query,
the 'sub lock' will fail. In fact, after $self->{lock_try} seconds,
the 'sub lock' will do the query even if the "Sprite.lck" exists,
and will not delete this lock file.
SUGGESTION 1: Set a timeout for the "Sprite.lck" file, that could be
checked just before the line that says
"select (undef, undef, undef, $self->{lock_sleep});"
SUGGESTION 2: Why name "Sprite.lck" for the lock file? Whit this, if
one table is locked, all tables will be, because the lock name is
the same. A better approach could be locking only the table in use,
naming the lock file something like "$table.lck".
BUG 7:
Update statement question: Why impose the parenthesis in the sql
statement? It seems not usual.
BUG 8:
This is not working: select USER from test.db where ID = 503
But this is working: select USER from test.db where ID = '503'
The reason seems to be inside sub parse_expression. The first
select will bring all rows because it treats as an attribution
instead of a comparation.
The second select works because it changes ID = '503' for ID eq '503'.
I think that %strtomap should have '=' => '=='. Any idea?
-----------------------------------------------------------------------
WISH LIST:
* Support join tables
* Support for field attributes (using an optional separated file) like
NOT NULL,primary key,integer,char(n)...