xref: /sqlite-3.40.0/src/test_rtree.c (revision 9508daa9)
1 /*
2 ** 2010 August 28
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 ** Code for testing all sorts of SQLite interfaces. This code
13 ** is not included in the SQLite library.
14 */
15 #include "sqlite3rtree.h"
16 #include <sqlite3.h>
17 #include <assert.h>
18 #include "tcl.h"
19 
20 typedef struct Cube Cube;
21 struct Cube {
22   double x;
23   double y;
24   double z;
25   double width;
26   double height;
27   double depth;
28 };
29 
30 static void cube_context_free(void *p){
31   sqlite3_free(p);
32 }
33 
34 static int gHere = 42;
35 
36 /*
37 ** Implementation of a simple r-tree geom callback to test for intersection
38 ** of r-tree rows with a "cube" shape. Cubes are defined by six scalar
39 ** coordinates as follows:
40 **
41 **   cube(x, y, z, width, height, depth)
42 **
43 ** The width, height and depth parameters must all be greater than zero.
44 */
45 static int cube_geom(
46   RtreeGeometry *p,
47   int nCoord,
48   double *aCoord,
49   int *piRes
50 ){
51   Cube *pCube = (Cube *)p->pUser;
52 
53   assert( p->pContext==(void *)&gHere );
54 
55   if( pCube==0 ){
56     if( p->nParam!=6 || nCoord!=6
57      || p->aParam[3]<=0.0 || p->aParam[4]<=0.0 || p->aParam[5]<=0.0
58     ){
59       return SQLITE_ERROR;
60     }
61     pCube = (Cube *)sqlite3_malloc(sizeof(Cube));
62     if( !pCube ){
63       return SQLITE_NOMEM;
64     }
65     pCube->x = p->aParam[0];
66     pCube->y = p->aParam[1];
67     pCube->z = p->aParam[2];
68     pCube->width = p->aParam[3];
69     pCube->height = p->aParam[4];
70     pCube->depth = p->aParam[5];
71 
72     p->pUser = (void *)pCube;
73     p->xDelUser = cube_context_free;
74   }
75 
76   assert( nCoord==6 );
77   *piRes = 0;
78   if( aCoord[0]<=(pCube->x+pCube->width)
79    && aCoord[1]>=pCube->x
80    && aCoord[2]<=(pCube->y+pCube->height)
81    && aCoord[3]>=pCube->y
82    && aCoord[4]<=(pCube->z+pCube->depth)
83    && aCoord[5]>=pCube->z
84   ){
85     *piRes = 1;
86   }
87 
88   return SQLITE_OK;
89 }
90 
91 static int register_cube_geom(
92   void * clientData,
93   Tcl_Interp *interp,
94   int objc,
95   Tcl_Obj *CONST objv[]
96 ){
97 #ifdef SQLITE_ENABLE_RTREE
98   extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
99   sqlite3 *db;
100 
101   if( objc!=2 ){
102     Tcl_WrongNumArgs(interp, 1, objv, "DB");
103     return TCL_ERROR;
104   }
105   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
106   sqlite3_rtree_geometry_callback(db, "cube", cube_geom, (void *)&gHere);
107 #endif
108   return TCL_OK;
109 }
110 
111 int Sqlitetestrtree_Init(Tcl_Interp *interp){
112   Tcl_CreateObjCommand(interp, "register_cube_geom", register_cube_geom, 0, 0);
113   return TCL_OK;
114 }
115 
116