mirror of
https://github.com/DBD-SQLite/DBD-SQLite
synced 2025-06-07 14:19:10 -04:00
106 lines
2.7 KiB
Perl
106 lines
2.7 KiB
Perl
use strict;
|
|
use warnings;
|
|
use lib "t/lib";
|
|
use SQLiteTest;
|
|
use Test::More;
|
|
use if -d ".git", "Test::FailWarnings";
|
|
|
|
BEGIN {
|
|
if (!has_compile_option('ENABLE_RTREE')) {
|
|
plan skip_all => 'RTREE is disabled for this DBD::SQLite';
|
|
}
|
|
}
|
|
|
|
# NOTE: It seems to be better to compare rounded values
|
|
# because stored coordinate values may have slight errors
|
|
# since SQLite 3.7.13 (DBD::SQLite 1.38_01).
|
|
|
|
sub is_deeply_approx {
|
|
my ($got, $expected, $name) = @_;
|
|
my $got_approx = [map { sprintf "%0.2f", $_ } @$got];
|
|
my $expected_approx = [map { sprintf "%0.2f", $_ } @$expected];
|
|
is_deeply($got_approx, $expected_approx, $name);
|
|
}
|
|
|
|
my @coords = (
|
|
# id, minX, maxX, minY, maxY
|
|
[1, 1, 200, 1, 200], # outside bounding box
|
|
[2, 25, 100, 25, 50],
|
|
[3, 50, 125, 40, 150],
|
|
[4, 25, 200, 125, 125], # hor. line
|
|
[5, 100, 100, 75, 175], # vert. line
|
|
[6, 100, 100, 75, 75], # point
|
|
[7, 150, 175, 150, 175]
|
|
);
|
|
|
|
my @test_regions = (
|
|
# minX, maxX, minY, maxY
|
|
[75, 75, 45, 45], # query point
|
|
[10, 140, 10, 175], # ... box
|
|
[30, 100, 75, 75] # ... hor. line
|
|
);
|
|
|
|
my @test_results = (
|
|
# results for contains tests (what does this region contain?)
|
|
[],
|
|
[2, 3, 5, 6],
|
|
[6],
|
|
|
|
# results for overlaps tests (what does this region overlap with?)
|
|
[1..3],
|
|
[1..6],
|
|
[1, 3, 5, 6]
|
|
);
|
|
|
|
# connect
|
|
my $dbh = connect_ok( RaiseError => 1 );
|
|
|
|
# TODO: test rtree and rtree_i32 tables
|
|
|
|
# create R* Tree table
|
|
$dbh->do(<<"") or die DBI::errstr;
|
|
CREATE VIRTUAL TABLE try_rtree
|
|
USING rtree_i32(id, minX, maxX, minY, maxY);
|
|
|
|
# populate it
|
|
my $insert_sth = $dbh->prepare(<<"") or die DBI::errstr;
|
|
INSERT INTO try_rtree VALUES (?,?,?,?,?)
|
|
|
|
for my $coord (@coords) {
|
|
ok $insert_sth->execute(@$coord);
|
|
}
|
|
|
|
# find by primary key
|
|
my $sql = "SELECT * FROM try_rtree WHERE id = ?";
|
|
|
|
my $idx = 0;
|
|
for my $id (1..2) {
|
|
my $results = $dbh->selectrow_arrayref($sql, undef, $id);
|
|
is_deeply_approx($results, $coords[$idx], "Coords for $id match");
|
|
$idx++;
|
|
}
|
|
|
|
# find contained regions
|
|
my $contained_sql = <<"";
|
|
SELECT id FROM try_rtree
|
|
WHERE minX >= ? AND maxX <= ?
|
|
AND minY >= ? AND maxY <= ?
|
|
|
|
# Since SQLite 3.7.13, coordinate values may have slight errors.
|
|
for my $region (@test_regions) {
|
|
my $results = $dbh->selectcol_arrayref($contained_sql, undef, @$region);
|
|
is_deeply_approx($results, shift @test_results);
|
|
}
|
|
|
|
# find overlapping regions
|
|
my $overlap_sql = <<"";
|
|
SELECT id FROM try_rtree
|
|
WHERE maxX >= ? AND minX <= ?
|
|
AND maxY >= ? AND minY <= ?
|
|
|
|
for my $region (@test_regions) {
|
|
my $results = $dbh->selectcol_arrayref($overlap_sql, undef, @$region);
|
|
is_deeply_approx($results, shift @test_results);
|
|
}
|
|
|
|
done_testing;
|