Question

I'm looking at the tutorial for Spatialite-Android, and I'm noticing the following code samples:

String query = "SELECT AsText(Transform(MakePoint(" + TEST_LON + ", " + TEST_LAT + ", 4326), 32632));";
sb.append("Execute query: ").append(query).append("\n");
try {
    Stmt stmt = db.prepare(query);
    if (stmt.step()) {
        String pointStr = stmt.column_string(0);
        sb.append("\t").append(TEST_LON + "/" + TEST_LAT + "/EPSG:4326").append(" = ")//
                .append(pointStr + "/EPSG:32632").append("...\n");
    }
    stmt.close();
} catch (Exception e) {
    e.printStackTrace();
    sb.append(ERROR).append(e.getLocalizedMessage()).append("\n");
}

In particular, I noticed that poor practice is done of simply stringing together a SQL query, instead of a more proper method, such as is used by the Android SQLite library. Is there a way that I can make Spatialite use true prepared statements?

Just to be clear, I'm looking for something like this, using the standard SQLite database in Android:

String query="SELECT * FROM table WHERE _id=?";
Cursor data=db.rawQuery(query,new String[]{id});
Was it helpful?

Solution

There are a few tricks. They all use the exec() call, which has 3 arguments for this version. The statement from the source code is:

public void exec(String sql, jsqlite.Callback cb, String args[])

A jsqlite.Callback is an interface, of which there can be several. But the best way seems to be using a db.get_table(query,args) function. %q is the effective replacement for ? in the Android SQLite representation. Here's the transformation of the given code:

String query = "SELECT AsText(Transform(MakePoint(%q, %q, 4326), 32632));";
TableResult result=db.get_table(query,new String[]{""+TEST_LONG,""+TEST_LAT});

From there, you just have to get the results from TableResult. There isn't a method call to get the results from here, you actually have to grab the publicly declared variable and manually parse through it. Here's an example of how that can be done.

TableResult result=db.get_table(query,new String[]{""+lng,""+lat});
Vector<String[]> rows=result.rows;
for (String[] row:rows)
{
    for (String val:row)
    {
        Log.v(TAG,val);
    }
}

If you aren't doing a select, try something like this:

TableResult result=new TableResult();
db.exec("ATTACH DATABASE %q AS newDb",result,new String[]{path});

I assume the same pattern will work for INSERTS and the like

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top