Skip to content

Commit

Permalink
Update @mfrager's SQLite patches (#126) to be more backwards-compatible.
Browse files Browse the repository at this point in the history
Mask hash value high-bit instead of only including 7/8 hash bytes.
  • Loading branch information
kasei committed Apr 7, 2015
1 parent 7cce0c4 commit 4475cf3
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 94 deletions.
3 changes: 3 additions & 0 deletions RDF-Trine-XS/lib/RDF/Trine/XS.pm
Expand Up @@ -11,6 +11,9 @@ our $VERSION = '2.000_01';
XSLoader::load "RDF::Trine::XS", $VERSION;

sub hash {
if (ref($_[0])) {
my $self = shift;
}
my $value = shift;
my $md5 = md5( encode('utf8', $value) );
return _hash( $md5 );
Expand Down
3 changes: 1 addition & 2 deletions RDF-Trine/lib/RDF/Trine/Store/DBI.pm
Expand Up @@ -1200,8 +1200,7 @@ using the same algorithm that Redland's mysql storage backend uses.

sub _mysql_hash;
sub _mysql_hash_pp {
if (ref($_[0]))
{
if (ref($_[0])) {
my $self = shift;
}
my $data = encode('utf8', shift);
Expand Down
83 changes: 16 additions & 67 deletions RDF-Trine/lib/RDF/Trine/Store/DBI/SQLite.pm
Expand Up @@ -84,92 +84,41 @@ sub new_with_config {
return $self;
}

=item C<< init >>
Creates the necessary tables in the underlying database.
=cut

sub _init {
my $self = shift;
my $dbh = $self->dbh;
my $name = $self->model_name;
my $id = $self->_mysql_hash( $name );
my $l = Log::Log4perl->get_logger("rdf.trine.store.dbi");

#$dbh->trace(2);
unless ($self->_table_exists("Literals")) {
$dbh->begin_work;
$dbh->do( <<"END" ) || do { $l->trace( $dbh->errstr ); $dbh->rollback; return };
CREATE TABLE Literals (
ID BIGINT PRIMARY KEY,
Value text NOT NULL,
Language text NOT NULL DEFAULT '',
Datatype text NOT NULL DEFAULT ''
);
END
$dbh->do( <<"END" ) || do { $l->trace( $dbh->errstr ); $dbh->rollback; return };
CREATE TABLE Resources (
ID BIGINT PRIMARY KEY,
URI text NOT NULL
);
END
$dbh->do( <<"END" ) || do { $l->trace( $dbh->errstr ); $dbh->rollback; return };
CREATE TABLE Bnodes (
ID BIGINT PRIMARY KEY,
Name text NOT NULL
);
END
$dbh->do( <<"END" ) || do { $l->trace( $dbh->errstr ); $dbh->rollback; return };
CREATE TABLE Models (
ID BIGINT PRIMARY KEY,
Name text NOT NULL
);
END

$dbh->commit or warn $dbh->errstr;
# SQLite only supports 64-bit SIGNED integers, so this hash function masks out
# the high-bit on hash values (unlike the superclass which produces full 64-bit
# integers)
sub _mysql_hash {
if (ref($_[0])) {
my $self = shift;
}

unless ($self->_table_exists("Statements${id}")) {
$dbh->do( <<"END" ) || do { $l->trace( $dbh->errstr ); return };
CREATE TABLE Statements${id} (
Subject BIGINT NOT NULL,
Predicate BIGINT NOT NULL,
Object BIGINT NOT NULL,
Context BIGINT NOT NULL DEFAULT 0,
PRIMARY KEY (Subject, Predicate, Object, Context)
);
END
# $dbh->do( "DELETE FROM Models WHERE ID = ${id}") || do { $l->trace( $dbh->errstr ); $dbh->rollback; return };
$dbh->do( "INSERT INTO Models (ID, Name) VALUES (${id}, ?)", undef, $name );
}

}

sub _mysql_hash
{
my $self = shift;
Carp::confess unless scalar(@_);
my $data = encode('utf8', shift);
my @data = unpack('C*', md5( $data ));
my $sum = Math::BigInt->new('0');
# CHANGE: 7 -> 6, Smaller numbers for Sqlite which does not support real 64-bit :(
foreach my $count (0 .. 6) {
foreach my $count (0 .. 7) {
my $data = Math::BigInt->new( $data[ $count ] ); #shift(@data);
my $part = $data << (8 * $count);
# warn "+ $part\n";
$sum += $part;
}
# warn "= $sum\n";
$sum = $sum->band(Math::BigInt->new('0x7fff_ffff_ffff_ffff'));
$sum =~ s/\D//; # get rid of the extraneous '+' that pops up under perl 5.6
return $sum;
}

=item C<< init >>
Creates the necessary tables in the underlying database.
=cut

sub init {
my $self = shift;
my $dbh = $self->dbh;
my $name = $self->model_name;
# Custom init for SQLite
$self->_init();
$self->SUPER::init();
my $id = $self->_mysql_hash( $name );

my $table = "Statements${id}";
Expand Down

0 comments on commit 4475cf3

Please sign in to comment.