📄 villa.pm
字号:
#=================================================================================================# Perl API of Villa, the basic API of QDBM# Copyright (C) 2000-2003 Mikio Hirabayashi# This file is part of QDBM, Quick Database Manager.# QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU# Lesser General Public License as published by the Free Software Foundation; either version# 2.1 of the License or any later version. QDBM is distributed in the hope that it will be# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more# details.# You should have received a copy of the GNU Lesser General Public License along with QDBM; if# not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA# 02111-1307 USA.#=================================================================================================package Villa;use strict;use warnings;require Tie::Hash;require Exporter;require DynaLoader;our @ISA = qw(Tie::Hash Exporter DynaLoader);our $VERSION = '1.0';bootstrap Villa $VERSION;use constant TRUE => 1; # boolean trueuse constant FALSE => 0; # boolean falseuse constant OREADER => 1 << 0; # open as a readeruse constant OWRITER => 1 << 1; # open as a writeruse constant OCREAT => 1 << 2; # a writer creatinguse constant OTRUNC => 1 << 3; # a writer truncatinguse constant ONOLCK => 1 << 4; # open without lockinguse constant CMPLEX => 0; # compare in lexical orderuse constant CMPDEC => 1; # compare decimal stringsuse constant DOVER => 0; # overwrite an existing valueuse constant DKEEP => 1; # keep an existing valueuse constant DDUP => 2; # allow duplication of recordsuse constant JFORWARD => 0; # step forwarduse constant JBACKWARD => 1; # step backwardmy(%handles) = (); # table of database namesour($errmsg) = "no error"; # message of the last error#=================================================================================================# public objects#=================================================================================================### use Villa;# Module `Villa' should be included in application codes.# An instance of the class `Villa' is used as a database handle.#### $Villa::errmsg;# Global Variable: The message of the last happened error.#### $villa = new Villa($name, $omode, $cmode);# Constructor: Get the database handle.# `$name' specifies the name of a database file.# `$omode' specifies the connection mode: `Villa::OWRITER' as a writer, `Villa::OREADER' as a# reader. If the mode is `Villa::OWRITER', the following may be added by bitwise or:# `Villa::OCREAT', which means it creates a new database if not exist, `Villa::OTRUNC', which# means it creates a new database regardless if one exists. Both of `Villa::OREADER' and# `Villa::OWRITER' can be added to by bitwise or: `Villa::ONOLCK', which means it opens a# database file without file locking. If it is undef, `Villa::OREADER' is specified.# `cmode' specifies the comparing function: `Villa::CMPLEX' comparing keys in lexical order,# `Villa::CMPDEC' comparing keys as decimal strings. The comparing function should be kept# same in the life of a database.# The return value is the database handle or undef if it is not successful.# While connecting as a writer, an exclusive lock is invoked to the database file.# While connecting as a reader, a shared lock is invoked to the database file. The thread# blocks until the lock is achieved. If `Villa::ONOLCK' is used, the application is responsible# for exclusion control.#sub new { my($class) = shift; my($name) = shift; my($omode) = shift; my($cmode) = shift; (defined($name) && length($name) > 0 && scalar(@_) == 0) || return undef(); (!$handles{$name}) || return undef(); (defined($omode)) || ($omode = OREADER); (defined($cmode)) || ($cmode = CMPLEX); my($villa) = plvlopen($name, $omode, $cmode); $errmsg = plvlerrmsg(); ($villa > 0) || return undef(); $handles{$name} = $villa; my $self = [$name, TRUE, undef(), undef(), undef(), undef()]; bless($self, $class); return $self;}### $bool = $villa->close();# Method: Close the database handle.# If successful, the return value is true, else, it is false.# Because the region of a closed handle is released, it becomes impossible to use the handle.# Updating a database is assured to be written when the handle is closed. If a writer opens# a database but does not close it appropriately, the database will be broken. If the# transaction is activated and not committed, it is aborted.#sub close { my($self) = shift; ($$self[1]) || return FALSE; (scalar(@_) == 0) || return FALSE; $$self[1] = FALSE; my($villa) = $handles{$$self[0]}; my($rv) = plvlclose($villa); $errmsg = plvlerrmsg(); delete($handles{$$self[0]}); return $rv;}### $bool = $villa->put($key, $val, $dmode);# Method: Store a record.# `$key' specifies a key. If it is undef, this method has no effect.# `$val' specifies a value. If it is undef, this method has no effect.# `$dmode' specifies behavior when the key overlaps, by the following values: `Villa::DOVER',# which means the specified value overwrites the existing one, `Villa::DKEEP', which means the# existing value is kept, `Villa::DDUP', which means duplication of keys is allowed. If it is# undef, `Villa::DOVER' is specified.# If successful, the return value is true, else, it is false.# A duplicated record is stored at the tail of the records of the same key. The cursor becomes# unavailable due to updating database.#sub put { my($self) = shift; ($$self[1]) || return FALSE; my($key) = shift; my($val) = shift; my($dmode) = shift; (scalar(@_) == 0) || return FALSE; (defined($key) && defined($val)) || return FALSE; (defined($dmode)) || ($dmode = DOVER); my($villa) = $handles{$$self[0]}; if($$self[2]){ local($_) = $key; $$self[2](); $key = $_; } if($$self[3]){ local($_) = $val; $$self[3](); $val = $_; } my($rv) = plvlput($villa, $key, length($key), $val, length($val), $dmode); $errmsg = plvlerrmsg(); return $rv;}### $bool = $villa->out($key);# Method: Delete a record.# `$key' specifies a key. If it is undef, this method has no effect.# If successful, the return value is true, else, it is false. False is returned when no# record corresponds to the specified key.# When the key of duplicated records is specified, the first record of the same key is deleted.# The cursor becomes unavailable due to updating database.#sub out { my($self) = shift; ($$self[1]) || return FALSE; my($key) = shift; (scalar(@_) == 0) || return FALSE; (defined($key)) || return FALSE; my($villa) = $handles{$$self[0]}; if($$self[2]){ local($_) = $key; $$self[2](); $key = $_; } my($rv) = plvlout($villa, $key, length($key)); $errmsg = plvlerrmsg(); return $rv;}### $str = $villa->get($key);# Method: Retrieve a record.# `$key' specifies a key. If it is undef, this method has no effect.# If successful, the return value is a scalar of the value of the corresponding record, else, it# is undef. undef is returned when no record corresponds to the specified key.# When the key of duplicated records is specified, the value of the first record of the same key# is selected.#sub get { my($self) = shift; ($$self[1]) || return undef(); my($key) = shift; (scalar(@_) == 0) || return undef(); (defined($key)) || return undef(); my($villa) = $handles{$$self[0]}; if($$self[2]){ local($_) = $key; $$self[2](); $key = $_; } my($rv) = plvlget($villa, $key, length($key)); $errmsg = plvlerrmsg(); if($rv && $$self[5]){ local($_) = $rv; $$self[5](); $rv = $_; } return $rv;}### $num = $villa->vnum($key);# Method: Get the number of records corresponding a key.# `$key' specifies a key. If it is undef, this method has no effect.# If successful, the return value is the size of the value of the corresponding record, else,# it is 0.#sub vnum { my($self) = shift; ($$self[1]) || return 0; my($key) = shift; (scalar(@_) == 0) || return 0; (defined($key)) || return 0; my($villa) = $handles{$$self[0]}; if($$self[2]){ local($_) = $key; $$self[2](); $key = $_; } my($rv) = plvlvnum($villa, $key, length($key)); $errmsg = plvlerrmsg(); return $rv;}### $bool = $villa->curfirst();# Method: Move the cursor to the first record.# If successful, the return value is true, else, it is false. False is returned if there is# no record in the database.#sub curfirst { my($self) = shift; ($$self[1]) || return FALSE; (scalar(@_) == 0) || return FALSE; my($villa) = $handles{$$self[0]}; my($rv) = plvlcurfirst($villa); $errmsg = plvlerrmsg(); return $rv;}### $bool = $villa->curlast();# Method: Move the cursor to the last record.# If successful, the return value is true, else, it is false. False is returned if there is# no record in the database.#sub curlast { my($self) = shift; ($$self[1]) || return FALSE; (scalar(@_) == 0) || return FALSE; my($villa) = $handles{$$self[0]}; my($rv) = plvlcurlast($villa); $errmsg = plvlerrmsg(); return $rv;}### $bool = $villa->curprev();# Method: Move the cursor to the previous record.# If successful, the return value is true, else, it is false. False is returned if there is# no previous record.#sub curprev { my($self) = shift; ($$self[1]) || return FALSE; (scalar(@_) == 0) || return FALSE; my($villa) = $handles{$$self[0]}; my($rv) = plvlcurprev($villa); $errmsg = plvlerrmsg(); return $rv;}### $bool = $villa->curnext();# Method: Move the cursor to the next record.# If successful, the return value is true, else, it is false. False is returned if there is# no next record.#sub curnext { my($self) = shift; ($$self[1]) || return FALSE; (scalar(@_) == 0) || return FALSE; my($villa) = $handles{$$self[0]}; my($rv) = plvlcurnext($villa); $errmsg = plvlerrmsg(); return $rv;}### $bool = $villa->curjump($key, $jmode);# Method: Move the cursor to positon around a record.# `$key' specifies a key. If it is undef, this method has no effect.# `$jmode' specifies detail adjustment: `Villa::JFORWARD', which means that the cursor is set# to the first record of the same key and that the cursor is set to the next substitute if# completely matching record does not exist, `Villa::JBACKWARD', which means that the cursor# is set to the last record of the same key and that the cursor is set to the previous# substitute if completely matching record does not exist. If it is undef, `Villa::JFORWARD'# is specified.# If successful, the return value is true, else, it is false. False is returned if there is# no record corresponding the condition.#sub curjump { my($self) = shift; ($$self[1]) || return FALSE; my($key) = shift; my($jmode) = shift; (scalar(@_) == 0) || return FALSE; (defined($key)) || return FALSE; (defined($jmode)) || ($jmode = JFORWARD); my($villa) = $handles{$$self[0]}; if($$self[2]){ local($_) = $key; $$self[2](); $key = $_; } my($rv) = plvlcurjump($villa, $key, length($key), $jmode); $errmsg = plvlerrmsg(); return $rv;}### $str = $villa->curkey();# Method: Get the key of the record where the cursor is.# If successful, the return value is a scalar of the key of the corresponding record, else, it# is undef. undef is returned when no record corresponds to the cursor.#sub curkey { my($self) = shift; ($$self[1]) || return undef(); (scalar(@_) == 0) || return undef(); my($villa) = $handles{$$self[0]}; my($rv) = plvlcurkey($villa); $errmsg = plvlerrmsg(); if($rv && $$self[4]){ local($_) = $rv; $$self[4](); $rv = $_; } return $rv;}### $str = $villa->curval();# Method: Get the value of the record where the cursor is.# If successful, the return value is a scalar of the value of the corresponding record, else, it# is undef. undef is returned when no record corresponds to the cursor.#sub curval { my($self) = shift; ($$self[1]) || return undef(); (scalar(@_) == 0) || return undef(); my($villa) = $handles{$$self[0]}; my($rv) = plvlcurval($villa); $errmsg = plvlerrmsg(); if($rv && $$self[5]){ local($_) = $rv; $$self[5](); $rv = $_; } return $rv;}##
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -