Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a prepared statement in Spatialite Android?

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});
like image 469
PearsonArtPhoto Avatar asked Nov 16 '13 02:11

PearsonArtPhoto


1 Answers

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

like image 121
PearsonArtPhoto Avatar answered Oct 22 '22 10:10

PearsonArtPhoto