Apache2-Translation
view release on metacpan or search on metacpan
lib/Apache2/Translation/MMapDB.pm view on Meta::CPAN
# MMapDB uses btrees. hence, keys are already ordered
sub list_keys {
my ($I)=@_;
my $k=$I->basekey;
my $db=$I->_db;
my ($idx)=$db->index_lookup($db->mainidx, @$k, 'actn');
return unless defined $idx;
my @res;
for( my $it=$db->index_iterator($idx); my ($key)=$it->(); ) {
push @res, [$key];
}
return @res;
}
# MMapDB uses btrees. hence, keys are already ordered
sub list_keys_and_uris {
my ($I, $key)=@_;
my $k=$I->basekey;
my $db=$I->_db;
my @res;
if( length $key ) {
my ($idx)=$db->index_lookup($db->mainidx, @$k, 'actn', $key);
return unless defined $idx;
for( my $it=$db->index_iterator($idx); my ($subkey)=$it->(); ) {
push @res, [$key, $subkey];
}
} else {
my ($idx)=$db->index_lookup($db->mainidx, @$k, 'actn');
return unless defined $idx;
for( my $it=$db->index_iterator($idx); ($key, $idx)=$it->(); ) {
for( my $jt=$db->index_iterator($idx); my ($subkey)=$jt->(); ) {
push @res, [$key, $subkey];
}
}
}
return @res;
}
sub begin {
my ($I)=@_;
die "ERROR: read-only mode\n" if( $I->readonly );
$I->_db->begin;
}
sub commit {
my ($I)=@_;
$I->_db->commit;
return "0 but true";
}
sub rollback {
my ($I)=@_;
$I->_db->rollback;
return "0 but true";
}
sub update {
my $I=shift;
my $old=shift;
my $new=shift;
return $I->insert($new) if $I->delete($old)>0;
return "0 but true";
}
sub insert {
my $I=shift;
my $new=shift;
die "ERROR: KEY must not contain spaces.\n" if( $new->[nKEY]=~/\s/ );
die "ERROR: URI must not contain spaces.\n" if( $new->[nURI]=~/\s/ );
$I->_db->insert([[@{$I->basekey}, 'actn', $new->[nKEY], $new->[nURI]],
pack("N2", @{$new}[nBLOCK, nORDER]), $new->[nACTION]]);
if( length $new->[nNOTE] ) {
$I->_db->insert([[@{$I->basekey}, 'note', $new->[nKEY], $new->[nURI]],
pack("N2", @{$new}[nBLOCK, nORDER]), $new->[nNOTE]]);
}
return 1;
}
sub delete {
my $I=shift;
my $old=shift;
my $db=$I->_db;
my $r=$db->data_record( $db->id_index_lookup($old->[oID]) );
return "0 but true" unless( $r );
my $ouri=pop @{$r->[0]};
my $okey=pop @{$r->[0]};
my $sort=pack('N2', @{$old}[oBLOCK, oORDER]);
if( $okey eq $old->[oKEY] and
$ouri eq $old->[oURI] and
$sort eq $r->[1] ) {
$db->delete_by_id($old->[oID]);
# delete note if any
foreach my $pos ($db->index_lookup($db->mainidx, @{$I->basekey},
'note', $okey, $ouri)) {
$r=$db->data_record( $pos );
if( $r->[1] eq $sort ) {
$db->delete_by_id($r->[3]);
last;
} elsif($r->[1] gt $sort) {
last;
}
}
return 1;
}
return "0 but true" unless( $r );
}
sub clear {
( run in 0.654 second using v1.01-cache-2.11-cpan-39bf76dae61 )