Re: INN::ovsqlite_client Perl module to manipulate an ovsqlite database
Bo Lindbergh <[email protected]> Mon, 1 Jan 2024 01:14:30 +0100
| Newsgroups | gmane.network.inn |
|---|---|
| Message-ID | <[email protected]> |
Version 1.001, for the delight of your git-am(1). /Bo Lindbergh -- inn-workers mailing list [email protected] https://lists.isc.org/mailman/listinfo/inn-workers
0001-INN-ovsqlite_client-version-1.001.patch
(application/octet-stream, 13.8 KB)
From dee891b806061c2df65d84850a7bddac3cd0b717 Mon Sep 17 00:00:00 2001 From: Bo Lindbergh <[email protected]> Date: Sat, 30 Dec 2023 06:04:17 +0100 Subject: [PATCH] INN::ovsqlite_client version 1.001 * Added convenience methods for requests that need repeating. * Updated sample program ovsqlite-dump to use the new methods. --- contrib/ovsqlite-dump.in | 108 ++++++++------- perl/INN/ovsqlite_client.pm | 256 ++++++++++++++++++++++++++++++++++-- 2 files changed, 296 insertions(+), 68 deletions(-) diff --git a/contrib/ovsqlite-dump.in b/contrib/ovsqlite-dump.in index 5112d0842..662ded594 100644 --- a/contrib/ovsqlite-dump.in +++ b/contrib/ovsqlite-dump.in @@ -21,71 +21,68 @@ use INN::ovsqlite_client qw(:all); sub dump_articles { my ($sock, $dst, $groupname) = @_; - my ($code, $errmsg, $low, $articles); + my ($code, $errmsg); my ($count); print STDERR $groupname, "... "; $count = 0; - $low = 1; - for (;;) { - $code = $sock->search_group( - groupname => $groupname, - low => $low, - cols => search_col_arrived | search_col_expires - | search_col_token | search_col_overview, - readsize => 0xFFFFF, - articles => $articles, - errmsg => $errmsg - ); - defined($errmsg) - and die "search_group: $errmsg"; - $code != response_artlist && $code != response_artlist_done - and die "search_group: Unexpected response code $code"; - foreach my $article (@{$articles}) { - print $dst join( - "\t", - "a", - @{$article}{qw(artnum arrived expires)}, - '@' . unpack("H*", $article->{token}) . '@', - $article->{overview} - ); - $count++; - } - $code == response_artlist_done - and last; - $low = $articles->[-1]->{artnum} + 1; - } + $code = $sock->search_group_all( + groupname => $groupname, + low => 1, + cols => search_col_arrived | search_col_expires + | search_col_token | search_col_overview, + readsize => 0xFFFFF, + errmsg => $errmsg, + callback => sub + { + my ($articles) = @_; + + foreach my $article (@{$articles}) { + print $dst join( + "\t", + "a", + @{$article}{qw(artnum arrived expires)}, + '@' . unpack("H*", $article->{token}) . '@', + $article->{overview} + ); + $count++; + } + 1; + }); + defined($errmsg) + and die "search_group_all: $errmsg"; + $code != response_artlist && $code != response_artlist_done + and die "search_group_all: Unexpected response code $code"; print STDERR $count, "\n"; } sub dump_groups { my ($sock, $dst) = @_; - my ($code, $errmsg, $groupid, $groups); + my ($code, $errmsg); - $groupid = 0; - for (;;) { - $code = $sock->list_groups( - groupid => $groupid, - groups => $groups, - errmsg => $errmsg - ); - defined($errmsg) - and die "list_groups: $errmsg"; - $code != response_grouplist && $code != response_grouplist_done - and die "list_groups: Unexpected response code $code\n"; - foreach my $group (@{$groups}) { - print $dst ( - join( - "\t", - "g", - @{$group}{qw(groupname low high count flag_alias)} - ), - "\n" - ); - dump_articles($sock, $dst, $group->{groupname}); - } - last if $code == response_grouplist_done; - } + $code = $sock->list_groups_all( + errmsg => $errmsg, + callback => sub + { + my ($groups) = @_; + + foreach my $group (@{$groups}) { + print $dst ( + join( + "\t", + "g", + @{$group}{qw(groupname low high count flag_alias)} + ), + "\n" + ); + dump_articles($sock, $dst, $group->{groupname}); + } + 1; + }); + defined($errmsg) + and die "list_groups_all: $errmsg"; + $code != response_grouplist && $code != response_grouplist_done + and die "list_groups_all: Unexpected response code $code\n"; } sub server_connect { @@ -106,3 +103,4 @@ sub server_connect { } dump_groups(server_connect(0), \*STDOUT); + diff --git a/perl/INN/ovsqlite_client.pm b/perl/INN/ovsqlite_client.pm index da2ef4286..9074402a3 100644 --- a/perl/INN/ovsqlite_client.pm +++ b/perl/INN/ovsqlite_client.pm @@ -7,7 +7,7 @@ package INN::ovsqlite_client; our ($VERSION); BEGIN { - $VERSION = 1.0; + $VERSION = 1.001; # The integer part of the above will be used # as the protocol version in the server handshake. } @@ -641,6 +641,64 @@ BEGIN { $code; } + my ($list_groups_all_in, $list_groups_all_out) = argparser( + [ + { + name => "callback", + required => 1, + }, + { + name => "readsize", + default => 0x20000, + }, + ], + [ + { + name => "errmsg", + }, + ], + ); + + sub list_groups_all + { + my $self=shift(@_); + my ($callback, $readsize); + my ($code, $errmsg, $groupid, $groups, $keep_on, $died); + + $list_groups_all_in->( + $callback, $readsize, + @_ + ); + $groupid = 0; + $keep_on = 1; + while ($keep_on) { + $code = $self->list_groups( + groupid => $groupid, + readsize => $readsize, + groups => $groups, + errmsg => $errmsg, + ); + $code==response_grouplist || $code==response_grouplist_done + or last; + eval { + $keep_on = $callback->($groups); + 1; + } or do { + $died = $@; + $keep_on = 0; + }; + $code==response_grouplist_done + and last; + } + $list_groups_all_out->( + $errmsg, + @_ + ); + defined($died) + and croak $died; + $code; + } + my ($add_article_in, $add_article_out) = argparser( [ { @@ -914,6 +972,82 @@ BEGIN { $code; } + my ($search_group_all_in, $search_group_all_out) = argparser( + [ + { + name => "callback", + required => 1, + }, + { + name => "groupname", + required => 1, + }, + { + name => "low", + required => 1, + }, + { + name => "high", + }, + { + name => "cols", + default => 0, + }, + { + name => "readsize", + default => 0x20000, + }, + ], + [ + { + name => "errmsg", + }, + ], + ); + + sub search_group_all + { + my $self = shift(@_); + my ($callback, $groupname, $low, $high, $cols, $readsize); + my ($articles, $code, $errmsg, $keep_on, $died); + + $search_group_all_in->( + $callback, $groupname, $low, $high, $cols, $readsize, + @_ + ); + $keep_on = 1; + while ($keep_on) { + $code = $self->search_group( + groupname => $groupname, + low => $low, + high => $high, + cols => $cols, + readsize => $readsize, + articles => $articles, + errmsg => $errmsg + ); + $code==response_artlist || $code==response_artlist_done + or last; + eval { + $keep_on = $callback->($articles); + 1; + } or do { + $died = $@; + $keep_on = 0; + }; + $code==response_artlist_done + and last; + $low = $articles->[-1]->{artnum}+1; + } + $search_group_all_out->( + $errmsg, + @_ + ); + defined($died) + and croak $died; + $code; + } + my ($start_expire_group_in, $start_expire_group_out) = argparser( [ { @@ -1027,6 +1161,56 @@ BEGIN { $code; } + my ($finish_expire_all_in, $finish_expire_all_out) = argparser( + [ + { + name => "callback", + required => 1, + }, + ], + [ + { + name => "errmsg", + }, + ], + ); + + sub finish_expire_all + { + my $self = shift(@_); + my ($callback); + my ($code, $errmsg, $keep_on, $died); + + $finish_expire_all_in->( + $callback, + @_ + ); + $keep_on = 1; + while ($keep_on) { + $code = $self->finish_expire( + errmsg => $errmsg, + ); + $code==response_ok || $code==response_done + or last; + eval { + $keep_on = $callback->(); + 1; + } or do { + $died = $@; + $keep_on = 0; + }; + $code==response_done + and last; + } + $finish_expire_all_out->( + $errmsg, + @_ + ); + defined($died) + and croak $died; + $code; + } + } 1; @@ -1045,26 +1229,31 @@ INN::ovsqlite_client - Talk to ovsqlite-server from Perl = INN::ovsqlite_client::->new( port => "/usr/local/news/run/ovsqlite.sock"); - $client->search_group( + $client->search_group_all( groupname => "news.software.nntp", low => 1, cols => search_col_overview, - articles => my $articles, - errmsg => my $errmsg + errmsg => my $errmsg, + callback => sub + { + my ($articles) = @_; + + foreach my $article (@{$articles}) { + print $article->{overview}; + } + 1; + } ); defined($errmsg) - and die "search_group: $errmsg"; - - foreach my $article (@{$articles}) { - print $article->{overview}; - } + and die "search_group: $errmsg"; =head1 DESCRIPTION C<INN::ovsqlite_client> implements the binary protocol used to communicate with the B<ovsqlite-server> daemon. It offers one instance method -for each request type. See F<ovsqlite-private.h> for details. +for each request type plus convenience methods for those requests +that need to be repeated. See F<ovsqlite-private.h> for details. Two examples of use within a Perl script are present in the F<contrib> directory (B<ovsqlite-dump> and B<ovsqlite-undump>). @@ -1247,6 +1436,19 @@ these keys: Z<> +=item list_groups_all + + $code = $client->list_groups_all( + callback => \&callback, + readsize => $readsize, # optional, default 0x20000 + errmsg => $errmsg, # optional output + ); + +This convenience method calls C<list_groups> repeatedly to fetch +information for all groups. The callback function is called +with the groups array reference as the only argument. It should return +a true value to keep iterating or a false value to terminate. + =item add_article $code = $client->add_artice( @@ -1276,7 +1478,7 @@ Z<> errmsg => $errmsg, # optional output ); -=item search_groups +=item search_group $code = $client->search_group( groupname => $groupname, @@ -1307,6 +1509,23 @@ these keys: Z<> +=item search_group_all + + $code = $client->search_group_all( + groupname => $groupname, + low => $low, + high => $high, # optional + cols => $cols, # optional, default 0x00 + callback => \&callback, + readsize => $readsize, # optional, default 0x20000 + errmsg => $errmsg, # optional output + ); + +This convenience methods calls C<search_group> repeatedly to fetch +information for all specified articles. The callback function is called +with the articles array reference as the only argument. It should return +a true value to keep iterating or a false value to terminate. + =item start_expire_group $code = $client->start_expire_group( @@ -1318,11 +1537,11 @@ Z<> $code = $client->expire_group( groupname => $groupname, - artnums => $artnums, + artnums => \@artnums, errmsg => $errmsg, # optional output ); -C<$artnums> must be a reference to an array of article numbers. +C<@artnums> must be an array of article numbers. =item finish_expire @@ -1330,6 +1549,17 @@ C<$artnums> must be a reference to an array of article numbers. errmsg => $errmsg, # optional output ); +=item finish_expire_all + + $code = $client->finish_expire_all( + callback => \&callback, + errmsg => $errmsg, # optional output + ); + +This convenience method calls C<finish_expire> repeatedly until done. +The callback function is called with no arguments and should return +a true value to keep iterating or a false value to terminate. + =back =head1 HISTORY -- 2.29.0