node-sqlite3 icon indicating copy to clipboard operation
node-sqlite3 copied to clipboard

Utilize sqlite3_expanded_sql to retrieve sql statements with bindings

Open smith-xyz opened this issue 1 year ago • 1 comments

Summary

With sqlite3_expanded_sql() you can retrieve the expanded version of the sql statement with the bindings. This is useful mostly for debugging purposes but could be useful if one has a disaster recovery process utilizing the prepared sql statements. Since sqlite3 has provided this as part of the api it may be nice to utilize here instead of creating an alternative process for creating that expanded sql.

Proposed implementation

Wondering if maybe Statement could have a expandedSql() method that could be used for this - always just pulls the sql:

db.serialize(() => {
  db.run("CREATE TABLE lorem (info TEXT)");
  const stmt = db.prepare("INSERT INTO lorem VALUES (?)");
  console.log(stmt.expandedSql()); // returns "INSERT INTO lorem VALUES (?)"
  stmt.bind("Ipsum");
  console.log(stmt.expandedSql()); // returns "INSERT INTO lorem VALUES ("Ipsum")"
  stmt.run();
  stmt.finalize();
});

Also could see this being in the trace as well.

Here is my quick use of the api performs the same result on a prepared statement:

int main(int argc, const char *const argv[])
{
  sqlite3 *db;
  sqlite3_open_v2(argv[1], &db, SQLITE_OPEN_READONLY, NULL);

  int rc;
  sqlite3_stmt *res;
  char *query = "";
  query = "SELECT count(*) FROM `test_table` WHERE `id` = ?;";
  rc = sqlite3_prepare_v2(db, query, -1, &res, 0);
  char *expanded = "";
  expanded = sqlite3_expanded_sql(res);
  printf("ExpandedQueryBefore=%s\n", query);

  if (rc == SQLITE_OK)
  {
    sqlite3_bind_int(res, 1, 1);
  }
 expanded = sqlite3_expanded_sql(res);
  printf("ExpandedQueryAfter=%s\n", expanded);
  int step = sqlite3_step(res);
 
  sqlite3_finalize(res);
  return 0;
}

smith-xyz avatar Feb 02 '23 17:02 smith-xyz