static int vbbox_open (sqlite3_vtab * pVTab, sqlite3_vtab_cursor ** ppCursor) { /* opening a new cursor */ sqlite3_stmt *stmt; gaiaOutBuffer sql_statement; int ret; char *sql; int ic; char *xname; VirtualBBoxCursorPtr cursor = (VirtualBBoxCursorPtr) sqlite3_malloc (sizeof (VirtualBBoxCursor)); if (cursor == NULL) return SQLITE_ERROR; cursor->pVtab = (VirtualBBoxPtr) pVTab; gaiaOutBufferInitialize (&sql_statement); gaiaAppendToOutBuffer (&sql_statement, "SELECT ROWID"); xname = gaiaDoubleQuotedSql (cursor->pVtab->MinX); sql = sqlite3_mprintf (",\"%s\"", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); xname = gaiaDoubleQuotedSql (cursor->pVtab->MinY); sql = sqlite3_mprintf (",\"%s\"", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); xname = gaiaDoubleQuotedSql (cursor->pVtab->MaxX); sql = sqlite3_mprintf (",\"%s\"", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); xname = gaiaDoubleQuotedSql (cursor->pVtab->MaxY); sql = sqlite3_mprintf (",\"%s\"", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); if (cursor->pVtab->ColSrid == NULL) gaiaAppendToOutBuffer (&sql_statement, ",NULL"); else { xname = gaiaDoubleQuotedSql (cursor->pVtab->ColSrid); sql = sqlite3_mprintf (",\"%s\"", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); } for (ic = 0; ic < cursor->pVtab->nColumns; ic++) { value_set_null (*(cursor->pVtab->Value + ic)); if (*(cursor->pVtab->Visible + ic) != 'Y') continue; xname = gaiaDoubleQuotedSql (*(cursor->pVtab->Column + ic)); sql = sqlite3_mprintf (",\"%s\"", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); } xname = gaiaDoubleQuotedSql (cursor->pVtab->table); sql = sqlite3_mprintf (" FROM \"%s\" WHERE ROWID >= ?", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); if (sql_statement.Error == 0 && sql_statement.Buffer != NULL) ret = sqlite3_prepare_v2 (cursor->pVtab->db, sql_statement.Buffer, strlen (sql_statement.Buffer), &stmt, NULL); else ret = SQLITE_ERROR; gaiaOutBufferReset (&sql_statement); if (ret != SQLITE_OK) { /* an error occurred */ cursor->eof = 1; return SQLITE_ERROR; } cursor->stmt = stmt; cursor->current_row = LONG64_MIN; cursor->eof = 0; *ppCursor = (sqlite3_vtab_cursor *) cursor; vbbox_read_row (cursor); return SQLITE_OK; }
static int vbbox_create (sqlite3 * db, void *pAux, int argc, const char *const *argv, sqlite3_vtab ** ppVTab, char **pzErr) { /* creates the virtual table connected to some BoundingBox table */ char *vtable = NULL; char *table = NULL; char *col_minx = NULL; char *col_miny = NULL; char *col_maxx = NULL; char *col_maxy = NULL; char *col_srid = NULL; char *x_force_wgs84 = NULL; int ret; int i; int i2; int len; int n_rows; int n_columns; const char *col_name; const char *col_type; int force_wgs84; char **results; char *sql; char *xname; gaiaOutBuffer sql_statement; VirtualBBoxPtr p_vt = NULL; if (pAux) pAux = pAux; /* unused arg warning suppression */ gaiaOutBufferInitialize (&sql_statement); /* checking for table_name */ if (argc >= 10) { vtable = gaiaDequotedSql ((char *) argv[2]); table = gaiaDequotedSql ((char *) argv[3]); col_minx = gaiaDequotedSql ((char *) argv[4]); col_miny = gaiaDequotedSql ((char *) argv[5]); col_maxx = gaiaDequotedSql ((char *) argv[6]); col_maxy = gaiaDequotedSql ((char *) argv[7]); col_srid = gaiaDequotedSql ((char *) argv[8]); x_force_wgs84 = gaiaDequotedSql ((char *) argv[9]); } else { *pzErr = sqlite3_mprintf ("[VirtualBBox module] CREATE VIRTUAL: illegal arg list {table_name, col_minx, col_miny, col_maxx, col_maxy, srid, longlat=1|0, columns}\n"); goto error; } if (strcmp (x_force_wgs84, "0") == 0) force_wgs84 = 0; else if (strcmp (x_force_wgs84, "1") == 0) force_wgs84 = 1; else { *pzErr = sqlite3_mprintf ("[VirtualBBox module] CREATE VIRTUAL: illegal arg list {table_name, col_minx, col_miny, col_maxx, col_maxy, srid, longlat=1|0, columns}\n"); goto error; } /* retrieving the base table columns */ xname = gaiaDoubleQuotedSql (table); sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", xname); free (xname); ret = sqlite3_get_table (db, sql, &results, &n_rows, &n_columns, NULL); sqlite3_free (sql); if (ret != SQLITE_OK) goto illegal; if (n_rows >= 1) { p_vt = (VirtualBBoxPtr) sqlite3_malloc (sizeof (VirtualBBox)); if (!p_vt) return SQLITE_NOMEM; p_vt->db = db; p_vt->p_cache = pAux; p_vt->nRef = 0; p_vt->zErrMsg = NULL; len = strlen (table); p_vt->table = sqlite3_malloc (len + 1); strcpy (p_vt->table, table); p_vt->nColumns = n_rows; p_vt->Column = sqlite3_malloc (sizeof (char *) * n_rows); p_vt->Type = sqlite3_malloc (sizeof (char *) * n_rows); p_vt->Visible = sqlite3_malloc (sizeof (char *) * n_rows); memset (p_vt->Visible, 'N', n_rows); p_vt->Value = sqlite3_malloc (sizeof (SqliteValuePtr) * n_rows); p_vt->Srid = atoi (col_srid); p_vt->ForceWGS84 = force_wgs84; #ifndef OMIT_PROJ /* including PROJ.4 */ if (p_vt->ForceWGS84) spatialite_e ("VirtualBBOX WARNING - WGS84 is requested, but PROJ4 support is currently disabled\n"); #endif /* end including PROJ.4 */ p_vt->ColSrid = NULL; p_vt->MinX = NULL; p_vt->MinY = NULL; p_vt->MaxX = NULL; p_vt->MaxY = NULL; p_vt->BBoxGeom = NULL; for (i = 0; i < n_rows; i++) { *(p_vt->Column + i) = NULL; *(p_vt->Type + i) = NULL; *(p_vt->Value + i) = value_alloc (); } for (i = 1; i <= n_rows; i++) { col_name = results[(i * n_columns) + 1]; col_type = results[(i * n_columns) + 2]; len = strlen (col_name); if (strcasecmp (col_name, col_minx) == 0) { p_vt->MinX = sqlite3_malloc (len + 1); strcpy (p_vt->MinX, col_name); } if (strcasecmp (col_name, col_miny) == 0) { p_vt->MinY = sqlite3_malloc (len + 1); strcpy (p_vt->MinY, col_name); } if (strcasecmp (col_name, col_maxx) == 0) { p_vt->MaxX = sqlite3_malloc (len + 1); strcpy (p_vt->MaxX, col_name); } if (strcasecmp (col_name, col_maxy) == 0) { p_vt->MaxY = sqlite3_malloc (len + 1); strcpy (p_vt->MaxY, col_name); } if (strcasecmp (col_name, col_srid) == 0) { p_vt->ColSrid = sqlite3_malloc (len + 1); strcpy (p_vt->ColSrid, col_name); } *(p_vt->Column + (i - 1)) = sqlite3_malloc (len + 1); strcpy (*(p_vt->Column + (i - 1)), col_name); len = strlen (col_type); *(p_vt->Type + (i - 1)) = sqlite3_malloc (len + 1); strcpy (*(p_vt->Type + (i - 1)), col_type); for (i2 = 10; i2 < argc; i2++) { char *extra_col = gaiaDequotedSql ((char *) argv[i2]); if (strcasecmp (extra_col, col_name) == 0) *(p_vt->Visible + (i - 1)) = 'Y'; free (extra_col); } } sqlite3_free_table (results); } else { sqlite3_free_table (results); goto illegal; } if (p_vt->MinX == NULL || p_vt->MinY == NULL || p_vt->MaxX == NULL || p_vt->MaxY == NULL) goto illegal; /* preparing the COLUMNs for this VIRTUAL TABLE */ xname = gaiaDoubleQuotedSql (vtable); sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (Geometry Polygon", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); for (i = 0; i < p_vt->nColumns; i++) { if (*(p_vt->Visible + i) != 'Y') continue; xname = gaiaDoubleQuotedSql (*(p_vt->Column + i)); sql = sqlite3_mprintf (", \"%s\" %s", xname, *(p_vt->Type + i)); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); } gaiaAppendToOutBuffer (&sql_statement, ")"); if (sql_statement.Error == 0 && sql_statement.Buffer != NULL) { if (sqlite3_declare_vtab (db, sql_statement.Buffer) != SQLITE_OK) { *pzErr = sqlite3_mprintf ("[VirtualBBox module] CREATE VIRTUAL: invalid SQL statement \"%s\"", sql); goto error; } gaiaOutBufferReset (&sql_statement); } else goto error; *ppVTab = (sqlite3_vtab *) p_vt; free (vtable); free (table); free (col_minx); free (col_miny); free (col_maxx); free (col_maxy); free (col_srid); free (x_force_wgs84); return SQLITE_OK; illegal: /* something is going the wrong way */ gaiaOutBufferReset (&sql_statement); if (p_vt) free_table (p_vt); *pzErr = sqlite3_mprintf ("[VirtualBBox module] '%s' isn't a valid BoundingBox table\n", table); error: if (vtable) free (vtable); if (table) free (table); if (col_minx) free (col_minx); if (col_miny) free (col_miny); if (col_maxx) free (col_maxx); if (col_maxy) free (col_maxy); if (col_srid) free (col_srid); if (x_force_wgs84) free (x_force_wgs84); gaiaOutBufferReset (&sql_statement); return SQLITE_ERROR; }
SPATIALITE_DECLARE void * spatialite_alloc_connection () { /* allocating and initializing an empty internal cache */ #ifdef GEOS_REENTRANT /* reentrant (thread-safe) initialization */ return spatialite_alloc_reentrant (); #else /* end GEOS_REENTRANT */ gaiaOutBufferPtr out; int i; struct splite_internal_cache *cache = NULL; struct splite_geos_cache_item *p; struct splite_xmlSchema_cache_item *p_xmlSchema; int pool_index; /* attempting to implicitly initialize the library */ spatialite_initialize (); /* locking the semaphore */ splite_cache_semaphore_lock (); pool_index = find_free_connection (); if (pool_index < 0) goto done; cache = malloc (sizeof (struct splite_internal_cache)); if (cache == NULL) { invalidate (pool_index); goto done; } cache->magic1 = SPATIALITE_CACHE_MAGIC1; cache->magic2 = SPATIALITE_CACHE_MAGIC2; cache->gpkg_mode = 0; cache->gpkg_amphibious_mode = 0; cache->decimal_precision = -1; cache->GEOS_handle = NULL; cache->PROJ_handle = NULL; cache->cutterMessage = NULL; cache->pool_index = pool_index; confirm (pool_index, cache); cache->gaia_geos_error_msg = NULL; cache->gaia_geos_warning_msg = NULL; cache->gaia_geosaux_error_msg = NULL; /* initializing an empty linked list of Topologies */ cache->firstTopology = NULL; cache->lastTopology = NULL; cache->next_topo_savepoint = 0; cache->topo_savepoint_name = NULL; cache->firstNetwork = NULL; cache->lastNetwork = NULL; cache->next_network_savepoint = 0; cache->network_savepoint_name = NULL; /* initializing the XML error buffers */ out = malloc (sizeof (gaiaOutBuffer)); gaiaOutBufferInitialize (out); cache->xmlParsingErrors = out; out = malloc (sizeof (gaiaOutBuffer)); gaiaOutBufferInitialize (out); cache->xmlSchemaValidationErrors = out; out = malloc (sizeof (gaiaOutBuffer)); gaiaOutBufferInitialize (out); cache->xmlXPathErrors = out; /* initializing the GEOS cache */ p = &(cache->cacheItem1); memset (p->gaiaBlob, '\0', 64); p->gaiaBlobSize = 0; p->crc32 = 0; p->geosGeom = NULL; p->preparedGeosGeom = NULL; p = &(cache->cacheItem2); memset (p->gaiaBlob, '\0', 64); p->gaiaBlobSize = 0; p->crc32 = 0; p->geosGeom = NULL; p->preparedGeosGeom = NULL; for (i = 0; i < MAX_XMLSCHEMA_CACHE; i++) { /* initializing the XmlSchema cache */ p_xmlSchema = &(cache->xmlSchemaCache[i]); p_xmlSchema->timestamp = 0; p_xmlSchema->schemaURI = NULL; p_xmlSchema->schemaDoc = NULL; p_xmlSchema->parserCtxt = NULL; p_xmlSchema->schema = NULL; } #include "cache_aux_3.h" /* initializing GEOS and PROJ.4 handles */ #ifndef OMIT_GEOS /* initializing GEOS */ cache->GEOS_handle = initGEOS_r (cache->geos_warning, cache->geos_error); #endif /* end GEOS */ #ifndef OMIT_PROJ /* initializing the PROJ.4 context */ cache->PROJ_handle = pj_ctx_alloc (); #endif /* end PROJ.4 */ done: /* unlocking the semaphore */ splite_cache_semaphore_unlock (); return cache; #endif }
static int vdbf_create (sqlite3 * db, void *pAux, int argc, const char *const *argv, sqlite3_vtab ** ppVTab, char **pzErr) { /* creates the virtual table connected to some DBF */ char *sql; VirtualDbfPtr p_vt; char path[2048]; char encoding[128]; const char *pEncoding = NULL; int len; const char *pPath = NULL; gaiaDbfFieldPtr pFld; int cnt; int col_cnt; int seed; int dup; int idup; char *xname; char **col_name = NULL; gaiaOutBuffer sql_statement; if (pAux) pAux = pAux; /* unused arg warning suppression */ /* checking for DBF PATH */ if (argc == 5) { pPath = argv[3]; len = strlen (pPath); if ((*(pPath + 0) == '\'' || *(pPath + 0) == '"') && (*(pPath + len - 1) == '\'' || *(pPath + len - 1) == '"')) { /* the path is enclosed between quotes - we need to dequote it */ strcpy (path, pPath + 1); len = strlen (path); *(path + len - 1) = '\0'; } else strcpy (path, pPath); pEncoding = argv[4]; len = strlen (pEncoding); if ((*(pEncoding + 0) == '\'' || *(pEncoding + 0) == '"') && (*(pEncoding + len - 1) == '\'' || *(pEncoding + len - 1) == '"')) { /* the charset-name is enclosed between quotes - we need to dequote it */ strcpy (encoding, pEncoding + 1); len = strlen (encoding); *(encoding + len - 1) = '\0'; } else strcpy (encoding, pEncoding); } else { *pzErr = sqlite3_mprintf ("[VirtualDbf module] CREATE VIRTUAL: illegal arg list {dbf_path, encoding}"); return SQLITE_ERROR; } p_vt = (VirtualDbfPtr) sqlite3_malloc (sizeof (VirtualDbf)); if (!p_vt) return SQLITE_NOMEM; p_vt->pModule = &my_dbf_module; p_vt->nRef = 0; p_vt->zErrMsg = NULL; p_vt->db = db; p_vt->dbf = gaiaAllocDbf (); /* trying to open file */ gaiaOpenDbfRead (p_vt->dbf, path, encoding, "UTF-8"); if (!(p_vt->dbf->Valid)) { /* something is going the wrong way; creating a stupid default table */ xname = gaiaDoubleQuotedSql ((const char *) argv[2]); sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (PKUID INTEGER)", xname); free (xname); if (sqlite3_declare_vtab (db, sql) != SQLITE_OK) { sqlite3_free (sql); *pzErr = sqlite3_mprintf ("[VirtualDbf module] cannot build a table from DBF\n"); return SQLITE_ERROR; } sqlite3_free (sql); *ppVTab = (sqlite3_vtab *) p_vt; return SQLITE_OK; } /* preparing the COLUMNs for this VIRTUAL TABLE */ gaiaOutBufferInitialize (&sql_statement); xname = gaiaDoubleQuotedSql (argv[2]); sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (PKUID INTEGER", xname); free (xname); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); /* checking for duplicate / illegal column names and antialising them */ col_cnt = 0; pFld = p_vt->dbf->Dbf->First; while (pFld) { /* counting DBF fields */ col_cnt++; pFld = pFld->Next; } col_name = malloc (sizeof (char *) * col_cnt); cnt = 0; seed = 0; pFld = p_vt->dbf->Dbf->First; while (pFld) { xname = gaiaDoubleQuotedSql (pFld->Name); dup = 0; for (idup = 0; idup < cnt; idup++) { if (strcasecmp (xname, *(col_name + idup)) == 0) dup = 1; } if (strcasecmp (xname, "\"PKUID\"") == 0) dup = 1; if (dup) { free (xname); sql = sqlite3_mprintf ("COL_%d", seed++); xname = gaiaDoubleQuotedSql (sql); sqlite3_free (sql); } if (pFld->Type == 'N') { if (pFld->Decimals > 0 || pFld->Length > 18) sql = sqlite3_mprintf (", \"%s\" DOUBLE", xname); else sql = sqlite3_mprintf (", \"%s\" INTEGER", xname); } else if (pFld->Type == 'F') sql = sqlite3_mprintf (", \"%s\" DOUBLE", xname); else sql = sqlite3_mprintf (", \"%s\" VARCHAR(%d)", xname, pFld->Length); gaiaAppendToOutBuffer (&sql_statement, sql); sqlite3_free (sql); *(col_name + cnt) = xname; cnt++; pFld = pFld->Next; } gaiaAppendToOutBuffer (&sql_statement, ")"); if (col_name) { /* releasing memory allocation for column names */ for (cnt = 0; cnt < col_cnt; cnt++) free (*(col_name + cnt)); free (col_name); } if (sql_statement.Error == 0 && sql_statement.Buffer != NULL) { if (sqlite3_declare_vtab (db, sql_statement.Buffer) != SQLITE_OK) { *pzErr = sqlite3_mprintf ("[VirtualDbf module] CREATE VIRTUAL: invalid SQL statement \"%s\"", sql_statement.Buffer); gaiaOutBufferReset (&sql_statement); return SQLITE_ERROR; } } gaiaOutBufferReset (&sql_statement); *ppVTab = (sqlite3_vtab *) p_vt; return SQLITE_OK; }
/* definitely releasing the slot */ struct splite_connection *p = &(splite_connection_pool[i]); p->conn_ptr = NULL; } #endif /* END obsolete partially thread-safe mode */ #ifdef GEOS_REENTRANT /* reentrant (thread-safe) initialization */ static void * spatialite_alloc_reentrant () { /* * allocating and initializing an empty internal cache * fully reentrant (thread-safe) version requiring GEOS >= 3.5.0 */ struct splite_internal_cache *cache = NULL; gaiaOutBufferPtr out; int i; struct splite_geos_cache_item *p; struct splite_xmlSchema_cache_item *p_xmlSchema; /* attempting to implicitly initialize the library */ spatialite_initialize (); cache = malloc (sizeof (struct splite_internal_cache)); if (cache == NULL) goto done; cache->magic1 = SPATIALITE_CACHE_MAGIC1; cache->magic2 = SPATIALITE_CACHE_MAGIC2; cache->gpkg_mode = 0; cache->gpkg_amphibious_mode = 0; cache->decimal_precision = -1; cache->GEOS_handle = NULL; cache->PROJ_handle = NULL; cache->cutterMessage = NULL; cache->pool_index = -1; cache->gaia_geos_error_msg = NULL; cache->gaia_geos_warning_msg = NULL; cache->gaia_geosaux_error_msg = NULL; /* initializing an empty linked list of Topologies */ cache->firstTopology = NULL; cache->lastTopology = NULL; cache->next_topo_savepoint = 0; cache->topo_savepoint_name = NULL; cache->firstNetwork = NULL; cache->lastNetwork = NULL; cache->next_network_savepoint = 0; cache->network_savepoint_name = NULL; /* initializing the XML error buffers */ out = malloc (sizeof (gaiaOutBuffer)); gaiaOutBufferInitialize (out); cache->xmlParsingErrors = out; out = malloc (sizeof (gaiaOutBuffer)); gaiaOutBufferInitialize (out); cache->xmlSchemaValidationErrors = out; out = malloc (sizeof (gaiaOutBuffer)); gaiaOutBufferInitialize (out); cache->xmlXPathErrors = out; /* initializing the GEOS cache */ p = &(cache->cacheItem1); memset (p->gaiaBlob, '\0', 64); p->gaiaBlobSize = 0; p->crc32 = 0; p->geosGeom = NULL; p->preparedGeosGeom = NULL; p = &(cache->cacheItem2); memset (p->gaiaBlob, '\0', 64); p->gaiaBlobSize = 0; p->crc32 = 0; p->geosGeom = NULL; p->preparedGeosGeom = NULL; for (i = 0; i < MAX_XMLSCHEMA_CACHE; i++) { /* initializing the XmlSchema cache */ p_xmlSchema = &(cache->xmlSchemaCache[i]); p_xmlSchema->timestamp = 0; p_xmlSchema->schemaURI = NULL; p_xmlSchema->schemaDoc = NULL; p_xmlSchema->parserCtxt = NULL; p_xmlSchema->schema = NULL; } /* initializing GEOS and PROJ.4 handles */ #ifndef OMIT_GEOS /* initializing GEOS */ cache->GEOS_handle = initGEOS_r (NULL, NULL); GEOSContext_setNoticeMessageHandler_r (cache->GEOS_handle, conn_geos_warning, cache); GEOSContext_setErrorMessageHandler_r (cache->GEOS_handle, conn_geos_error, cache); #endif /* end GEOS */ #ifndef OMIT_PROJ /* initializing the PROJ.4 context */ cache->PROJ_handle = pj_ctx_alloc (); #endif /* end PROJ.4 */ done: return cache; }