Compare commits

...

17 commits
0.01 ... master

Author SHA1 Message Date
643985ee60 New Homepage 2025-02-21 23:28:42 +08:00
5e3601243d Update UnQLite Version 2024-06-11 16:13:33 +08:00
Tokuhiro Matsuno
c38e901619 Checking in changes prior to tagging of version 0.05.
Changelog diff is:

diff --git Changes Changes
index b22c1b5..3386ce5 100644
--- Changes
+++ Changes
@@ -2,6 +2,10 @@ Revision history for Perl extension Unqlite

 {{$NEXT}}

+0.05 2014-12-23T22:55:15Z
+
+    - Doc fix
+
 0.04 2014-08-30T09:33:52Z

     - Fixed packaging issue.
2014-12-24 07:55:57 +09:00
Tokuhiro Matsuno
033c847b60 [Doc fix] UnQLite doesn't exports constants. 2014-12-24 07:54:34 +09:00
Tokuhiro Matsuno
c29b1690d7 Checking in changes prior to tagging of version 0.04.
Changelog diff is:

diff --git Changes Changes
index ad21f65..b22c1b5 100644
--- Changes
+++ Changes
@@ -2,6 +2,10 @@ Revision history for Perl extension Unqlite

 {{$NEXT}}

+0.04 2014-08-30T09:33:52Z
+
+    - Fixed packaging issue.
+
 0.03 2013-07-18T03:14:07Z

     - more OPEN consts as mode argument
2014-08-30 18:37:42 +09:00
tokuhirom
c6e3d80dd1 Checking in changes prior to tagging of version 0.03.
Changelog diff is:

diff --git a/Changes b/Changes
index fb8ef47..ad21f65 100644
--- a/Changes
+++ b/Changes
@@ -2,6 +2,12 @@ Revision history for Perl extension Unqlite

 {{$NEXT}}

+0.03 2013-07-18T03:14:07Z
+
+    - more OPEN consts as mode argument
+      we do not only want to create databases
+      (Reini Urban)
+
 0.02 2013-07-05T06:42:59Z

     - Store RC to magic to fix race condition
2013-07-18 12:14:37 +09:00
Tokuhiro Matsuno
e1861918ec Merge pull request #3 from rurban/master
more OPEN consts as mode argument
2013-07-17 20:12:45 -07:00
Reini Urban
9d0c7708fb more OPEN consts as mode argument
we do not only want to create databases
2013-07-17 12:42:59 -05:00
tokuhirom
e727b98d1d Checking in changes prior to tagging of version 0.02.
Changelog diff is:

diff --git a/Changes b/Changes
index 947f86c..fb8ef47 100644
--- a/Changes
+++ b/Changes
@@ -2,6 +2,13 @@ Revision history for Perl extension Unqlite

 {{$NEXT}}

+0.02 2013-07-05T06:42:59Z
+
+    - Store RC to magic to fix race condition
+      (charsbar)
+    - Added `tie` interface.
+      (charsbar)
+
 0.01 2013-07-03T19:02:44Z

     - original version
2013-07-05 15:43:37 +09:00
Tokuhiro Matsuno
21f038767e Merge pull request #2 from charsbar/magic
Store RC in a magic object
2013-07-04 23:02:12 -07:00
Kenichi Ishigaki
efa2f598fa magic rc 2013-07-05 12:51:20 +09:00
Tokuhiro Matsuno
89c490c504 Merge pull request #1 from charsbar/tie
tie interface
2013-07-03 21:53:57 -07:00
Kenichi Ishigaki
38116a08c5 better use UNQLITE_OK as there may be other errors 2013-07-04 13:48:22 +09:00
Kenichi Ishigaki
879640f4c5 fixed EXISTS 2013-07-04 13:40:10 +09:00
Kenichi Ishigaki
a94bdc6ca2 fixed DELETE for a nonexistent entry 2013-07-04 13:32:39 +09:00
Kenichi Ishigaki
317b78815a oops 2013-07-04 13:23:50 +09:00
Kenichi Ishigaki
008d6ea2f3 tie interface 2013-07-04 13:20:58 +09:00
10 changed files with 60594 additions and 60060 deletions

View file

@ -12,8 +12,6 @@ use utf8;
use Module::Build; use Module::Build;
use File::Basename; use File::Basename;
use File::Spec; use File::Spec;
use CPAN::Meta;
use CPAN::Meta::Prereqs;
my %args = ( my %args = (
license => 'perl', license => 'perl',
@ -29,9 +27,12 @@ my %args = (
script_files => [glob('script/*'), glob('bin/*')], script_files => [glob('script/*'), glob('bin/*')],
c_source => [qw(unqlite)], c_source => [qw(unqlite)],
PL_files => {},
test_files => ((-d '.git' || $ENV{RELEASE_TESTING}) && -d 'xt') ? 't/ xt/' : 't/', test_files => ((-d '.git' || $ENV{RELEASE_TESTING}) && -d 'xt') ? 't/ xt/' : 't/',
recursive_test_files => 1, recursive_test_files => 1,
); );
if (-d 'share') { if (-d 'share') {
$args{share_dir} = 'share'; $args{share_dir} = 'share';
@ -50,20 +51,15 @@ my $builder = Module::Build->subclass(
)->new(%args); )->new(%args);
$builder->create_build_script(); $builder->create_build_script();
my $mbmeta = CPAN::Meta->load_file('MYMETA.json'); use File::Copy;
my $meta = CPAN::Meta->load_file('META.json');
my $prereqs_hash = CPAN::Meta::Prereqs->new( print "cp META.json MYMETA.json\n";
$meta->prereqs copy("META.json","MYMETA.json") or die "Copy failed(META.json): $!";
)->with_merged_prereqs(
CPAN::Meta::Prereqs->new($mbmeta->prereqs) if (-f 'META.yml') {
)->as_string_hash; print "cp META.yml MYMETA.yml\n";
my $mymeta = CPAN::Meta->new( copy("META.yml","MYMETA.yml") or die "Copy failed(META.yml): $!";
{ } else {
%{$meta->as_struct}, print "There is no META.yml... You may install this module from the repository...\n";
prereqs => $prereqs_hash }
}
);
print "Merging cpanfile prereqs to MYMETA.yml\n";
$mymeta->save('MYMETA.yml', { version => 1.4 });
print "Merging cpanfile prereqs to MYMETA.json\n";
$mymeta->save('MYMETA.json', { version => 2 });

21
Changes
View file

@ -2,6 +2,27 @@ Revision history for Perl extension Unqlite
{{$NEXT}} {{$NEXT}}
0.05 2014-12-23T22:55:15Z
- Doc fix
0.04 2014-08-30T09:33:52Z
- Fixed packaging issue.
0.03 2013-07-18T03:14:07Z
- more OPEN consts as mode argument
we do not only want to create databases
(Reini Urban)
0.02 2013-07-05T06:42:59Z
- Store RC to magic to fix race condition
(charsbar)
- Added `tie` interface.
(charsbar)
0.01 2013-07-03T19:02:44Z 0.01 2013-07-03T19:02:44Z
- original version - original version

View file

@ -4,7 +4,7 @@
"tokuhirom <tokuhirom@gmail.com>" "tokuhirom <tokuhirom@gmail.com>"
], ],
"dynamic_config" : 0, "dynamic_config" : 0,
"generated_by" : "Minilla/v0.5.5, CPAN::Meta::Converter version 2.130880", "generated_by" : "Minilla/v2.2.0, CPAN::Meta::Converter version 2.141520",
"license" : [ "license" : [
"perl_5" "perl_5"
], ],
@ -21,21 +21,21 @@
"share", "share",
"eg", "eg",
"examples", "examples",
"author" "author",
"builder"
] ]
}, },
"prereqs" : { "prereqs" : {
"configure" : { "configure" : {
"requires" : { "requires" : {
"CPAN::Meta" : "0",
"CPAN::Meta::Prereqs" : "0",
"Module::Build" : "0.38" "Module::Build" : "0.38"
} }
}, },
"develop" : { "develop" : {
"requires" : { "requires" : {
"Test::CPAN::Meta" : "0", "Test::CPAN::Meta" : "0",
"Test::MinimumVersion" : "0.10108", "Test::MinimumVersion::Fast" : "0.04",
"Test::PAUSE::Permissions" : "0.04",
"Test::Pod" : "1.41", "Test::Pod" : "1.41",
"Test::Spellunker" : "v0.2.7" "Test::Spellunker" : "v0.2.7"
} }
@ -63,5 +63,9 @@
"web" : "https://github.com/tokuhirom/UnQLite" "web" : "https://github.com/tokuhirom/UnQLite"
} }
}, },
"version" : "0.01" "version" : "0.05",
"x_contributors" : [
"Kenichi Ishigaki <ishigaki@cpan.org>",
"Reini Urban <rurban@cpanel.net>"
]
} }

View file

@ -6,23 +6,28 @@ UnQLite - Perl bindings for UnQLite
use UnQLite; use UnQLite;
my $db = UnQLite->open('foo.db'); my $db = UnQLite->open('foo.db', UnQLite::UNQLITE_OPEN_READWRITE|UnQLite::UNQLITE_OPEN_CREATE);
$db->kv_store('foo', 'bar'); $db->kv_store('foo', 'bar');
say $db->kv_fetch('foo'); # => bar say $db->kv_fetch('foo'); # => bar
$db->kv_delete('foo'); $db->kv_delete('foo');
undef $db; # close database undef $db; # close database
# tie interface
tie my %hash, 'UnQLite', 'foo.db', UnQLite::UNQLITE_OPEN_READWRITE;
$hash{foo} = 'bar';
say $hash{foo}; # => bar
# DESCRIPTION # DESCRIPTION
UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL database engine. UnQLite is a document store database similar to MongoDB, Redis, CouchDB etc. as well a standard Key/Value store similar to BerkeleyDB, LevelDB, etc. UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL database engine. UnQLite is a document store database similar to MongoDB, Redis, CouchDB etc. as well a standard Key/Value store similar to BerkeleyDB, LevelDB, etc.
This module is Perl5 binding for UnQLite. This module is Perl5 binding for UnQLite.
If you want to know more information about UnQLite, see [http://unqlite.org/](http://unqlite.org/). If you want to know more information about UnQLite, see [https://unqlite.symisc.net/](https://unqlite.symisc.net/).
This version of UnQLite.pm does not provides document store feature. Patches welcome. This version of UnQLite.pm does not provides document store feature. Patches welcome.
__You can use UnQLite.pm as DBM__. **You can use UnQLite.pm as DBM**.
# METHODS # METHODS
@ -30,6 +35,17 @@ __You can use UnQLite.pm as DBM__.
Open the database. Open the database.
Modes:
UnQLite::UNQLITE_OPEN_CREATE (Default)
UnQLite::UNQLITE_OPEN_READONLY
UnQLite::UNQLITE_OPEN_READWRITE
UnQLite::UNQLITE_OPEN_EXCLUSIVE
UnQLite::UNQLITE_OPEN_TEMP_DB
UnQLite::UNQLITE_OPEN_OMIT_JOURNALING
UnQLite::UNQLITE_OPEN_IN_MEMORY
UnQLite::UNQLITE_OPEN_MMAP
- `$db->kv_store($key, $value);` - `$db->kv_store($key, $value);`
Store the entry to database. Store the entry to database.
@ -102,11 +118,11 @@ Here is example code:
Return true if succeeded, false otherwise. Return true if succeeded, false otherwise.
- `$cursor->seek($key, $opt=UNQLITE_CURSOR_MATCH_EXACT)` - `$cursor->seek($key, $opt=UnQLite::UNQLITE_CURSOR_MATCH_EXACT)`
Seek cursor to ` $key `. Seek cursor to ` $key `.
You can specify the option as ` $opt `. Please see [http://unqlite.org/c\_api/unqlite\_kv\_cursor.html](http://unqlite.org/c\_api/unqlite\_kv\_cursor.html) for more details. You can specify the option as ` $opt `. Please see [http://unqlite.org/c\_api/unqlite\_kv\_cursor.html](http://unqlite.org/c_api/unqlite_kv_cursor.html) for more details.
Return true if succeeded, false otherwise. Return true if succeeded, false otherwise.

View file

@ -2,17 +2,29 @@ package UnQLite;
use 5.008005; use 5.008005;
use strict; use strict;
use warnings; use warnings;
use Carp ();
our $VERSION = "0.01"; our $VERSION = "0.05";
our $rc = 0; our $rc = 0;
use XSLoader; use XSLoader;
XSLoader::load(__PACKAGE__, $VERSION); XSLoader::load(__PACKAGE__, $VERSION);
sub rc { $UnQLite::rc } sub TIEHASH {
my $class = shift;
my $self = $class->open(@_) or Carp::croak $class->errstr;
$self->cursor_init;
}
sub rc {
my $self = shift;
my $_rc = _rc($self);
defined $_rc ? $rc = $_rc : $rc;
}
sub errstr { sub errstr {
my $self = shift; my $self = shift;
my $rc = $self->rc;
if ($rc==UnQLite::UNQLITE_OK()) { return "UNQLITE_OK" } if ($rc==UnQLite::UNQLITE_OK()) { return "UNQLITE_OK" }
if ($rc==UNQLITE_NOMEM()) { return "UNQLITE_NOMEM" } if ($rc==UNQLITE_NOMEM()) { return "UNQLITE_NOMEM" }
if ($rc==UNQLITE_ABORT()) { return "UNQLITE_ABORT" } if ($rc==UNQLITE_ABORT()) { return "UNQLITE_ABORT" }
@ -46,6 +58,12 @@ sub cursor_init {
package UnQLite::Cursor; package UnQLite::Cursor;
sub rc {
my $self = shift;
my $_rc = _rc($self->[0]);
defined $_rc ? $UnQLite::rc = $_rc : $UnQLite::rc;
}
sub first_entry { sub first_entry {
my $self = shift; my $self = shift;
_first_entry($self->[0]); _first_entry($self->[0]);
@ -96,6 +114,62 @@ sub DESTROY {
_release($self->[0], $self->[1]); _release($self->[0], $self->[1]);
} }
# tie interface
sub FETCH {
my ($self, $key) = @_;
$self->[1]->kv_fetch($key);
}
sub STORE {
my ($self, $key, $value) = @_;
$self->[1]->kv_store($key, $value) or Carp::croak $self->[1]->errstr;
$value;
}
sub DELETE {
my ($self, $key) = @_;
my $prev = $self->[1]->kv_fetch($key);
my $errstr = $self->[1]->errstr;
return unless $errstr && $errstr eq 'UNQLITE_OK';
$self->[1]->kv_delete($key) or Carp::croak $self->[1]->errstr;
$prev;
}
sub FIRSTKEY {
my $self = shift;
$self->first_entry or return;
$self->key;
}
sub NEXTKEY {
my $self = shift;
$self->next_entry or return;
$self->key;
}
sub EXISTS {
my ($self, $key) = @_;
$self->[1]->kv_fetch($key) and return 1;
my $errstr = $self->[1]->errstr;
return $errstr && $errstr eq 'UNQLITE_OK' ? 1 : 0;
}
sub CLEAR {
my $self = shift;
$self->first_entry or return;
$self->delete_entry while $self->valid_entry;
return;
}
sub SCALAR {
my $self = shift;
$self->first_entry or return;
my $ct = 1;
$ct++ while $self->next_entry && $self->valid_entry;
return $ct;
}
1; 1;
__END__ __END__
@ -111,12 +185,17 @@ UnQLite - Perl bindings for UnQLite
use UnQLite; use UnQLite;
my $db = UnQLite->open('foo.db'); my $db = UnQLite->open('foo.db', UnQLite::UNQLITE_OPEN_READWRITE|UnQLite::UNQLITE_OPEN_CREATE);
$db->kv_store('foo', 'bar'); $db->kv_store('foo', 'bar');
say $db->kv_fetch('foo'); # => bar say $db->kv_fetch('foo'); # => bar
$db->kv_delete('foo'); $db->kv_delete('foo');
undef $db; # close database undef $db; # close database
# tie interface
tie my %hash, 'UnQLite', 'foo.db', UnQLite::UNQLITE_OPEN_READWRITE;
$hash{foo} = 'bar';
say $hash{foo}; # => bar
=head1 DESCRIPTION =head1 DESCRIPTION
UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL database engine. UnQLite is a document store database similar to MongoDB, Redis, CouchDB etc. as well a standard Key/Value store similar to BerkeleyDB, LevelDB, etc. UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL database engine. UnQLite is a document store database similar to MongoDB, Redis, CouchDB etc. as well a standard Key/Value store similar to BerkeleyDB, LevelDB, etc.
@ -137,6 +216,17 @@ B<You can use UnQLite.pm as DBM>.
Open the database. Open the database.
Modes:
UnQLite::UNQLITE_OPEN_CREATE (Default)
UnQLite::UNQLITE_OPEN_READONLY
UnQLite::UNQLITE_OPEN_READWRITE
UnQLite::UNQLITE_OPEN_EXCLUSIVE
UnQLite::UNQLITE_OPEN_TEMP_DB
UnQLite::UNQLITE_OPEN_OMIT_JOURNALING
UnQLite::UNQLITE_OPEN_IN_MEMORY
UnQLite::UNQLITE_OPEN_MMAP
=item C<< $db->kv_store($key, $value); >> =item C<< $db->kv_store($key, $value); >>
Store the entry to database. Store the entry to database.
@ -213,7 +303,7 @@ Seek cursor to previous entry.
Return true if succeeded, false otherwise. Return true if succeeded, false otherwise.
=item C<< $cursor->seek($key, $opt=UNQLITE_CURSOR_MATCH_EXACT) >> =item C<< $cursor->seek($key, $opt=UnQLite::UNQLITE_CURSOR_MATCH_EXACT) >>
Seek cursor to C< $key >. Seek cursor to C< $key >.

View file

@ -19,14 +19,21 @@ extern "C" {
#define XS_STRUCT2OBJ(sv, class, obj) \ #define XS_STRUCT2OBJ(sv, class, obj) \
sv = newSViv(PTR2IV(obj)); \ sv = newSViv(PTR2IV(obj)); \
sv_magic(sv, sv_2mortal(newSViv(UNQLITE_OK)), PERL_MAGIC_ext, NULL, 0); \
sv = newRV_noinc(sv); \ sv = newRV_noinc(sv); \
sv_bless(sv, gv_stashpv(class, 1)); \ sv_bless(sv, gv_stashpv(class, 1)); \
SvREADONLY_on(sv); SvREADONLY_on(sv);
#define SETRC(rc) \ #define SETRC(rc, self) \
{ \ { \
SV * i = get_sv("UnQLite::rc", GV_ADD); \ SV * i = get_sv("UnQLite::rc", GV_ADD); \
SvIV_set(i, rc); \ SvIV_set(i, rc); \
if (SvROK(self)) { \
MAGIC *_mg = mg_find(SvRV(self), PERL_MAGIC_ext); \
if (_mg) { \
SvIV_set(_mg->mg_obj, rc); \
} \
} \
} }
MODULE = UnQLite PACKAGE = UnQLite MODULE = UnQLite PACKAGE = UnQLite
@ -35,34 +42,44 @@ PROTOTYPES: DISABLE
BOOT: BOOT:
HV* stash = gv_stashpvn("UnQLite", strlen("UnQLite"), TRUE); HV* stash = gv_stashpvn("UnQLite", strlen("UnQLite"), TRUE);
newCONSTSUB(stash, "UNQLITE_OK", newSViv(UNQLITE_OK)); #define _XSTR(s) _STR(s)
newCONSTSUB(stash, "UNQLITE_NOMEM", newSViv(UNQLITE_NOMEM)); #define _STR(s) #s
newCONSTSUB(stash, "UNQLITE_ABORT", newSViv(UNQLITE_ABORT)); #define UnConst(c) newCONSTSUB(stash, "UNQ"_XSTR(c), newSViv(UNQ##c))
newCONSTSUB(stash, "UNQLITE_IOERR", newSViv(UNQLITE_IOERR)); UnConst(LITE_OK);
newCONSTSUB(stash, "UNQLITE_CORRUPT", newSViv(UNQLITE_CORRUPT)); UnConst(LITE_NOMEM);
newCONSTSUB(stash, "UNQLITE_LOCKED", newSViv(UNQLITE_LOCKED)); UnConst(LITE_ABORT);
newCONSTSUB(stash, "UNQLITE_BUSY", newSViv(UNQLITE_BUSY)); UnConst(LITE_IOERR);
newCONSTSUB(stash, "UNQLITE_DONE", newSViv(UNQLITE_DONE)); UnConst(LITE_CORRUPT);
newCONSTSUB(stash, "UNQLITE_PERM", newSViv(UNQLITE_PERM)); UnConst(LITE_LOCKED);
newCONSTSUB(stash, "UNQLITE_NOTIMPLEMENTED", newSViv(UNQLITE_NOTIMPLEMENTED)); UnConst(LITE_BUSY);
newCONSTSUB(stash, "UNQLITE_NOTFOUND", newSViv(UNQLITE_NOTFOUND)); UnConst(LITE_DONE);
newCONSTSUB(stash, "UNQLITE_NOOP", newSViv(UNQLITE_NOOP)); UnConst(LITE_PERM);
newCONSTSUB(stash, "UNQLITE_INVALID", newSViv(UNQLITE_INVALID)); UnConst(LITE_NOTIMPLEMENTED);
newCONSTSUB(stash, "UNQLITE_EOF", newSViv(UNQLITE_EOF)); UnConst(LITE_NOTFOUND);
newCONSTSUB(stash, "UNQLITE_UNKNOWN", newSViv(UNQLITE_UNKNOWN)); UnConst(LITE_NOOP);
newCONSTSUB(stash, "UNQLITE_LIMIT", newSViv(UNQLITE_LIMIT)); UnConst(LITE_INVALID);
newCONSTSUB(stash, "UNQLITE_EXISTS", newSViv(UNQLITE_EXISTS)); UnConst(LITE_EOF);
newCONSTSUB(stash, "UNQLITE_EMPTY", newSViv(UNQLITE_EMPTY)); UnConst(LITE_UNKNOWN);
newCONSTSUB(stash, "UNQLITE_COMPILE_ERR", newSViv(UNQLITE_COMPILE_ERR)); UnConst(LITE_LIMIT);
newCONSTSUB(stash, "UNQLITE_VM_ERR", newSViv(UNQLITE_VM_ERR)); UnConst(LITE_EXISTS);
newCONSTSUB(stash, "UNQLITE_FULL", newSViv(UNQLITE_FULL)); UnConst(LITE_EMPTY);
newCONSTSUB(stash, "UNQLITE_CANTOPEN", newSViv(UNQLITE_CANTOPEN)); UnConst(LITE_COMPILE_ERR);
newCONSTSUB(stash, "UNQLITE_READ_ONLY", newSViv(UNQLITE_READ_ONLY)); UnConst(LITE_VM_ERR);
newCONSTSUB(stash, "UNQLITE_LOCKERR", newSViv(UNQLITE_LOCKERR)); UnConst(LITE_FULL);
UnConst(LITE_CANTOPEN);
newCONSTSUB(stash, "UNQLITE_CURSOR_MATCH_EXACT", newSViv(UNQLITE_CURSOR_MATCH_EXACT)); UnConst(LITE_READ_ONLY);
newCONSTSUB(stash, "UNQLITE_CURSOR_MATCH_LE", newSViv(UNQLITE_CURSOR_MATCH_LE)); UnConst(LITE_LOCKERR);
newCONSTSUB(stash, "UNQLITE_CURSOR_MATCH_GE", newSViv(UNQLITE_CURSOR_MATCH_GE)); UnConst(LITE_OPEN_READONLY);
UnConst(LITE_OPEN_READWRITE);
UnConst(LITE_OPEN_CREATE);
UnConst(LITE_OPEN_EXCLUSIVE);
UnConst(LITE_OPEN_TEMP_DB);
UnConst(LITE_OPEN_OMIT_JOURNALING);
UnConst(LITE_OPEN_IN_MEMORY);
UnConst(LITE_OPEN_MMAP);
UnConst(LITE_CURSOR_MATCH_EXACT);
UnConst(LITE_CURSOR_MATCH_LE);
UnConst(LITE_CURSOR_MATCH_GE);
SV* SV*
open(klass, filename, mode=UNQLITE_OPEN_CREATE) open(klass, filename, mode=UNQLITE_OPEN_CREATE)
@ -75,10 +92,29 @@ PREINIT:
int rc; int rc;
CODE: CODE:
rc = unqlite_open(&pdb, filename, mode); rc = unqlite_open(&pdb, filename, mode);
SETRC(rc);
if (rc == UNQLITE_OK) { if (rc == UNQLITE_OK) {
XS_STRUCT2OBJ(sv, klass, pdb); XS_STRUCT2OBJ(sv, klass, pdb);
SETRC(rc, sv);
RETVAL = sv; RETVAL = sv;
} else {
SETRC(rc, &PL_sv_undef);
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
SV* _rc(self)
SV *self
PREINIT:
MAGIC *mg;
CODE:
if (SvROK(self)) {
mg = mg_find(SvRV(self), PERL_MAGIC_ext);
if (mg) {
RETVAL = newSVsv(mg->mg_obj);
} else {
RETVAL = &PL_sv_undef;
}
} else { } else {
RETVAL = &PL_sv_undef; RETVAL = &PL_sv_undef;
} }
@ -101,7 +137,7 @@ CODE:
key_c = SvPV(key_sv, key_l); key_c = SvPV(key_sv, key_l);
data_c = SvPV(data_sv, data_l); data_c = SvPV(data_sv, data_l);
rc = unqlite_kv_store(pdb, key_c, key_l, data_c, data_l); rc = unqlite_kv_store(pdb, key_c, key_l, data_c, data_l);
SETRC(rc); SETRC(rc, self);
if (rc==UNQLITE_OK) { if (rc==UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {
@ -126,7 +162,7 @@ CODE:
key_c = SvPV(key_sv, key_l); key_c = SvPV(key_sv, key_l);
data_c = SvPV(data_sv, data_l); data_c = SvPV(data_sv, data_l);
rc = unqlite_kv_append(pdb, key_c, key_l, data_c, data_l); rc = unqlite_kv_append(pdb, key_c, key_l, data_c, data_l);
SETRC(rc); SETRC(rc, self);
if (rc==UNQLITE_OK) { if (rc==UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {
@ -147,7 +183,7 @@ CODE:
unqlite *pdb = XS_STATE(unqlite*, self); unqlite *pdb = XS_STATE(unqlite*, self);
key_c = SvPV(key_sv, key_l); key_c = SvPV(key_sv, key_l);
rc = unqlite_kv_delete(pdb, key_c, key_l); rc = unqlite_kv_delete(pdb, key_c, key_l);
SETRC(rc); SETRC(rc, self);
if (rc==UNQLITE_OK) { if (rc==UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {
@ -173,14 +209,14 @@ CODE:
/* Allocate a buffer big enough to hold the record content */ /* Allocate a buffer big enough to hold the record content */
rc = unqlite_kv_fetch(pdb, key_c, key_l, NULL, &nbytes); rc = unqlite_kv_fetch(pdb, key_c, key_l, NULL, &nbytes);
SETRC(rc); SETRC(rc, self);
if (rc!=UNQLITE_OK) { if (rc!=UNQLITE_OK) {
RETVAL = &PL_sv_undef; RETVAL = &PL_sv_undef;
goto last; goto last;
} }
Newxz(buf, nbytes, char); Newxz(buf, nbytes, char);
rc = unqlite_kv_fetch(pdb, key_c, key_l, buf, &nbytes); rc = unqlite_kv_fetch(pdb, key_c, key_l, buf, &nbytes);
SETRC(rc); SETRC(rc, self);
sv = newSVpv(buf, nbytes); sv = newSVpv(buf, nbytes);
Safefree(buf); Safefree(buf);
RETVAL = sv; RETVAL = sv;
@ -196,7 +232,7 @@ PREINIT:
CODE: CODE:
unqlite *pdb = XS_STATE(unqlite*, self); unqlite *pdb = XS_STATE(unqlite*, self);
rc = unqlite_close(pdb); rc = unqlite_close(pdb);
SETRC(rc); SETRC(rc, &PL_sv_undef);
SV* SV*
_cursor_init(self) _cursor_init(self)
@ -208,9 +244,10 @@ PREINIT:
CODE: CODE:
unqlite *pdb = XS_STATE(unqlite*, self); unqlite *pdb = XS_STATE(unqlite*, self);
rc = unqlite_kv_cursor_init(pdb, &cursor); rc = unqlite_kv_cursor_init(pdb, &cursor);
SETRC(rc); SETRC(rc, self);
if (rc == UNQLITE_OK) { if (rc == UNQLITE_OK) {
sv = newSViv(PTR2IV(cursor)); sv = newSViv(PTR2IV(cursor));
sv_magic(sv, sv_2mortal(newSViv(UNQLITE_OK)), PERL_MAGIC_ext, NULL, 0);
sv = newRV_noinc(sv); sv = newRV_noinc(sv);
SvREADONLY_on(sv); SvREADONLY_on(sv);
RETVAL = sv; RETVAL = sv;
@ -223,6 +260,24 @@ OUTPUT:
MODULE = UnQLite PACKAGE = UnQLite::Cursor MODULE = UnQLite PACKAGE = UnQLite::Cursor
SV* _rc(self)
SV *self
PREINIT:
MAGIC *mg;
CODE:
if (SvROK(self)) {
mg = mg_find(SvRV(self), PERL_MAGIC_ext);
if (mg) {
RETVAL = newSVsv(mg->mg_obj);
} else {
RETVAL = &PL_sv_undef;
}
} else {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
SV* SV*
_first_entry(self) _first_entry(self)
SV * self; SV * self;
@ -232,7 +287,7 @@ PREINIT:
CODE: CODE:
unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self); unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self);
rc = unqlite_kv_cursor_first_entry(cursor); rc = unqlite_kv_cursor_first_entry(cursor);
SETRC(rc); SETRC(rc, self);
if (rc == UNQLITE_OK) { if (rc == UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {
@ -264,7 +319,7 @@ PREINIT:
CODE: CODE:
unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self); unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self);
rc = unqlite_kv_cursor_next_entry(cursor); rc = unqlite_kv_cursor_next_entry(cursor);
SETRC(rc); SETRC(rc, self);
if (rc == UNQLITE_OK) { if (rc == UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {
@ -282,7 +337,7 @@ PREINIT:
CODE: CODE:
unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self); unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self);
rc = unqlite_kv_cursor_last_entry(cursor); rc = unqlite_kv_cursor_last_entry(cursor);
SETRC(rc); SETRC(rc, self);
if (rc == UNQLITE_OK) { if (rc == UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {
@ -300,7 +355,7 @@ PREINIT:
CODE: CODE:
unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self); unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self);
rc = unqlite_kv_cursor_prev_entry(cursor); rc = unqlite_kv_cursor_prev_entry(cursor);
SETRC(rc); SETRC(rc, self);
if (rc == UNQLITE_OK) { if (rc == UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {
@ -320,14 +375,14 @@ PREINIT:
CODE: CODE:
unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self); unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self);
rc = unqlite_kv_cursor_key(cursor, NULL, &nbytes); rc = unqlite_kv_cursor_key(cursor, NULL, &nbytes);
SETRC(rc); SETRC(rc, self);
if (rc!=UNQLITE_OK) { if (rc!=UNQLITE_OK) {
RETVAL = &PL_sv_undef; RETVAL = &PL_sv_undef;
goto last; goto last;
} }
Newxz(buf, nbytes, char); Newxz(buf, nbytes, char);
rc = unqlite_kv_cursor_key(cursor, buf, &nbytes); rc = unqlite_kv_cursor_key(cursor, buf, &nbytes);
SETRC(rc); SETRC(rc, self);
sv = newSVpv(buf, nbytes); sv = newSVpv(buf, nbytes);
Safefree(buf); Safefree(buf);
RETVAL = sv; RETVAL = sv;
@ -346,14 +401,14 @@ PREINIT:
CODE: CODE:
unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self); unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self);
rc = unqlite_kv_cursor_data(cursor, NULL, &nbytes); rc = unqlite_kv_cursor_data(cursor, NULL, &nbytes);
SETRC(rc); SETRC(rc, self);
if (rc!=UNQLITE_OK) { if (rc!=UNQLITE_OK) {
RETVAL = &PL_sv_undef; RETVAL = &PL_sv_undef;
goto last; goto last;
} }
Newxz(buf, nbytes, char); Newxz(buf, nbytes, char);
rc = unqlite_kv_cursor_data(cursor, buf, &nbytes); rc = unqlite_kv_cursor_data(cursor, buf, &nbytes);
SETRC(rc); SETRC(rc, self);
sv = newSVpv(buf, nbytes); sv = newSVpv(buf, nbytes);
Safefree(buf); Safefree(buf);
RETVAL = sv; RETVAL = sv;
@ -383,7 +438,7 @@ CODE:
unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self); unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self);
key = SvPV(key_s, len); key = SvPV(key_s, len);
rc = unqlite_kv_cursor_seek(cursor, key, len, opt); rc = unqlite_kv_cursor_seek(cursor, key, len, opt);
SETRC(rc); SETRC(rc, self);
if (rc == UNQLITE_OK) { if (rc == UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {
@ -400,7 +455,7 @@ PREINIT:
CODE: CODE:
unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self); unqlite_kv_cursor *cursor = XS_STATE(unqlite_kv_cursor*, self);
rc = unqlite_kv_cursor_delete_entry(cursor); rc = unqlite_kv_cursor_delete_entry(cursor);
SETRC(rc); SETRC(rc, self);
if (rc == UNQLITE_OK) { if (rc == UNQLITE_OK) {
RETVAL = &PL_sv_yes; RETVAL = &PL_sv_yes;
} else { } else {

46
t/03_tie.t Normal file
View file

@ -0,0 +1,46 @@
use strict;
use Test::More;
use File::Temp qw(tempdir);
use UnQLite;
my $tmp = tempdir( CLEANUP => 1 );
{
my $db = UnQLite->open("$tmp/foo.db");
isa_ok($db, 'UnQLite');
ok($db->kv_store("foo", "bar"));
is($db->kv_fetch('foo'), 'bar');
ok($db->kv_delete('foo'));
is($db->kv_fetch('foo'), undef);
$db->kv_store('yay', 'yap');
$db->kv_append('yay', 'po');
is($db->kv_fetch('yay'), 'yappo');
is($db->rc,0);
}
{
ok -e "$tmp/foo.db", "foo.db exists";
tie my %hash, 'UnQLite', "$tmp/foo.db";
# stored data can be retrieved again?
is($hash{yay}, 'yappo');
$hash{foo} = 'baz';
is($hash{foo}, 'baz');
$hash{delete} = 'delete';
is(delete $hash{delete}, 'delete');
is(delete $hash{delete}, undef);
ok(exists $hash{foo});
ok(!exists $hash{delete});
is(join(" ", sort keys %hash), "foo yay");
is(join(" ", sort values %hash), "baz yappo");
is(scalar %hash, 2);
%hash = ();
is(join(" ", sort keys %hash), "");
is(join(" ", sort values %hash), "");
is(scalar %hash, undef);
}
done_testing;

View file

@ -1,5 +1,4 @@
/* * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Symisc Systems, S.U.A.R.L [M.I.A.G Mrad Chems Eddine <chm@symisc.net>].
* Copyright (C) 2012, 2013 Symisc Systems, S.U.A.R.L [M.I.A.G Mrad Chems Eddine <chm@symisc.net>].
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -22,4 +21,3 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,14 @@
/* This file was automatically generated. Do not edit (Except for compile time directives)! */ /* This file was automatically generated. Do not edit (Except for compile time directives)! */
#ifndef _UNQLITE_H_ #ifndef _UNQLITE_H_
#define _UNQLITE_H_ #define _UNQLITE_H_
/* Make sure we can call this stuff from C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* Symisc UnQLite: An Embeddable NoSQL (Post Modern) Database Engine. * Symisc UnQLite: An Embeddable NoSQL (Post Modern) Database Engine.
* Copyright (C) 2012-2013, Symisc Systems http://unqlite.org/ * Copyright (C) 2012-2019, Symisc Systems http://unqlite.org/
* Version 1.1.6 * Version 1.1.9
* For information on licensing, redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES * For information on licensing, redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES
* please contact Symisc Systems via: * please contact Symisc Systems via:
* legal@symisc.net * legal@symisc.net
@ -14,7 +18,7 @@
* http://unqlite.org/licensing.html * http://unqlite.org/licensing.html
*/ */
/* /*
* Copyright (C) 2012, 2013 Symisc Systems, S.U.A.R.L [M.I.A.G Mrad Chems Eddine <chm@symisc.net>]. * Copyright (C) 2012, 2019 Symisc Systems, S.U.A.R.L [M.I.A.G Mrad Chems Eddine <chm@symisc.net>].
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -38,7 +42,7 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/* $SymiscID: unqlite.h v1.1 UNIX|WIN32/64 2012-11-02 02:10 stable <chm@symisc.net> $ */ /* $SymiscID: unqlite.h v1.3 Win10 2108-04-27 02:35:11 stable <chm@symisc.net> $ */
#include <stdarg.h> /* needed for the definition of va_list */ #include <stdarg.h> /* needed for the definition of va_list */
/* /*
* Compile time engine version, signature, identification in the symisc source tree * Compile time engine version, signature, identification in the symisc source tree
@ -49,18 +53,18 @@
* [unqlite_lib_copyright()] for more information. * [unqlite_lib_copyright()] for more information.
*/ */
/* /*
* The UNQLITE_VERSION C preprocessor macroevaluates to a string literal * The UNQLITE_VERSION C preprocessor macro evaluates to a string literal
* that is the unqlite version in the format "X.Y.Z" where X is the major * that is the unqlite version in the format "X.Y.Z" where X is the major
* version number and Y is the minor version number and Z is the release * version number and Y is the minor version number and Z is the release
* number. * number.
*/ */
#define UNQLITE_VERSION "1.1.6" #define UNQLITE_VERSION "1.1.9"
/* /*
* The UNQLITE_VERSION_NUMBER C preprocessor macro resolves to an integer * The UNQLITE_VERSION_NUMBER C preprocessor macro resolves to an integer
* with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same * with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
* numbers used in [UNQLITE_VERSION]. * numbers used in [UNQLITE_VERSION].
*/ */
#define UNQLITE_VERSION_NUMBER 1001006 #define UNQLITE_VERSION_NUMBER 1001009
/* /*
* The UNQLITE_SIG C preprocessor macro evaluates to a string * The UNQLITE_SIG C preprocessor macro evaluates to a string
* literal which is the public signature of the unqlite engine. * literal which is the public signature of the unqlite engine.
@ -68,14 +72,14 @@
* generated Server MIME header as follows: * generated Server MIME header as follows:
* Server: YourWebServer/x.x unqlite/x.x.x \r\n * Server: YourWebServer/x.x unqlite/x.x.x \r\n
*/ */
#define UNQLITE_SIG "unqlite/1.1.6" #define UNQLITE_SIG "unqlite/1.1.9"
/* /*
* UnQLite identification in the Symisc source tree: * UnQLite identification in the Symisc source tree:
* Each particular check-in of a particular software released * Each particular check-in of a particular software released
* by symisc systems have an unique identifier associated with it. * by symisc systems have an unique identifier associated with it.
* This macro hold the one associated with unqlite. * This macro hold the one associated with unqlite.
*/ */
#define UNQLITE_IDENT "unqlite:b172a1e2c3f62fb35c8e1fb2795121f82356cad6" #define UNQLITE_IDENT "unqlite:29c173b1-ac2c-4b49-93ba-e600619e304e"
/* /*
* Copyright notice. * Copyright notice.
* If you have any questions about the licensing situation, please * If you have any questions about the licensing situation, please
@ -85,7 +89,7 @@
* licensing@symisc.net * licensing@symisc.net
* contact@symisc.net * contact@symisc.net
*/ */
#define UNQLITE_COPYRIGHT "Copyright (C) Symisc Systems, S.U.A.R.L [Mrad Chems Eddine <chm@symisc.net>] 2012-2013, http://unqlite.org/" #define UNQLITE_COPYRIGHT "Copyright (C) Symisc Systems, S.U.A.R.L [Mrad Chems Eddine <chm@symisc.net>] 2012-2019, http://unqlite.org/"
/* Forward declaration to public objects */ /* Forward declaration to public objects */
typedef struct unqlite_io_methods unqlite_io_methods; typedef struct unqlite_io_methods unqlite_io_methods;
@ -399,7 +403,7 @@ typedef sxi64 unqlite_int64;
* Each options require a variable number of arguments. * Each options require a variable number of arguments.
* The [unqlite_vm_config()] interface will return UNQLITE_OK on success, any other return * The [unqlite_vm_config()] interface will return UNQLITE_OK on success, any other return
* value indicates failure. * value indicates failure.
* There are many options but the most importants are: UNQLITE_VM_CONFIG_OUTPUT which install * There are many options but the most important are: UNQLITE_VM_CONFIG_OUTPUT which install
* a VM output consumer callback, UNQLITE_VM_CONFIG_HTTP_REQUEST which parse and register * a VM output consumer callback, UNQLITE_VM_CONFIG_HTTP_REQUEST which parse and register
* a HTTP request and UNQLITE_VM_CONFIG_ARGV_ENTRY which populate the $argv array. * a HTTP request and UNQLITE_VM_CONFIG_ARGV_ENTRY which populate the $argv array.
* For a full discussion on the configuration verbs and their expected parameters, please * For a full discussion on the configuration verbs and their expected parameters, please
@ -651,14 +655,14 @@ struct unqlite_vfs {
typedef sxu64 pgno; typedef sxu64 pgno;
/* /*
* A database disk page is represented by an instance * A database disk page is represented by an instance
* of the follwoing structure. * of the following structure.
*/ */
typedef struct unqlite_page unqlite_page; typedef struct unqlite_page unqlite_page;
struct unqlite_page struct unqlite_page
{ {
unsigned char *zData; /* Content of this page */ unsigned char *zData; /* Content of this page */
void *pUserData; /* Extra content */ void *pUserData; /* Extra content */
pgno pgno; /* Page number for this page */ pgno iPage; /* Page number for this page */
}; };
/* /*
* UnQLite handle to the underlying Key/Value Storage Engine (See below). * UnQLite handle to the underlying Key/Value Storage Engine (See below).
@ -783,9 +787,9 @@ struct unqlite_kv_methods
#define UNQLITE_JOURNAL_FILE_SUFFIX "_unqlite_journal" #define UNQLITE_JOURNAL_FILE_SUFFIX "_unqlite_journal"
#endif #endif
/* /*
* Call Context - Error Message Serverity Level. * Call Context - Error Message Severity Level.
* *
* The following constans are the allowed severity level that can * The following constants are the allowed severity level that can
* passed as the second argument to the [unqlite_context_throw_error()] or * passed as the second argument to the [unqlite_context_throw_error()] or
* [unqlite_context_throw_error_format()] interfaces. * [unqlite_context_throw_error_format()] interfaces.
* Refer to the official documentation for additional information. * Refer to the official documentation for additional information.
@ -803,6 +807,7 @@ UNQLITE_APIEXPORT int unqlite_open(unqlite **ppDB,const char *zFilename,unsigned
UNQLITE_APIEXPORT int unqlite_config(unqlite *pDb,int nOp,...); UNQLITE_APIEXPORT int unqlite_config(unqlite *pDb,int nOp,...);
UNQLITE_APIEXPORT int unqlite_close(unqlite *pDb); UNQLITE_APIEXPORT int unqlite_close(unqlite *pDb);
/* Key/Value (KV) Store Interfaces */ /* Key/Value (KV) Store Interfaces */
UNQLITE_APIEXPORT int unqlite_kv_store(unqlite *pDb,const void *pKey,int nKeyLen,const void *pData,unqlite_int64 nDataLen); UNQLITE_APIEXPORT int unqlite_kv_store(unqlite *pDb,const void *pKey,int nKeyLen,const void *pData,unqlite_int64 nDataLen);
UNQLITE_APIEXPORT int unqlite_kv_append(unqlite *pDb,const void *pKey,int nKeyLen,const void *pData,unqlite_int64 nDataLen); UNQLITE_APIEXPORT int unqlite_kv_append(unqlite *pDb,const void *pKey,int nKeyLen,const void *pData,unqlite_int64 nDataLen);
@ -945,5 +950,7 @@ UNQLITE_APIEXPORT const char * unqlite_lib_version(void);
UNQLITE_APIEXPORT const char * unqlite_lib_signature(void); UNQLITE_APIEXPORT const char * unqlite_lib_signature(void);
UNQLITE_APIEXPORT const char * unqlite_lib_ident(void); UNQLITE_APIEXPORT const char * unqlite_lib_ident(void);
UNQLITE_APIEXPORT const char * unqlite_lib_copyright(void); UNQLITE_APIEXPORT const char * unqlite_lib_copyright(void);
#ifdef __cplusplus
}
#endif
#endif /* _UNQLITE_H_ */ #endif /* _UNQLITE_H_ */