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