Function: sqlite-execute

sqlite-execute is a function defined in sqlite.c.

Signature

(sqlite-execute DB QUERY &optional VALUES)

Documentation

Execute a non-select SQL statement.

If VALUES is non-nil, it should be a vector or a list of values to bind when executing a statement like

   insert into foo values (?, ?, ...)

Value is the number of affected rows.

View in manual

Source Code

// Defined in /usr/src/emacs/src/sqlite.c
{
  check_sqlite (db, false);
  CHECK_STRING (query);
  if (!(NILP (values) || CONSP (values) || VECTORP (values)))
    xsignal1 (Qsqlite_error, build_string ("VALUES must be a list or a vector"));

  sqlite3 *sdb = XSQLITE (db)->db;
  Lisp_Object errmsg = Qnil,
    encoded = encode_string (query);
  sqlite3_stmt *stmt = NULL;

  /* We only execute the first statement -- if there's several
     (separated by a semicolon), the subsequent statements won't be
     done.  */
  int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL);
  if (ret != SQLITE_OK)
    {
      if (stmt != NULL)
	{
	  sqlite3_finalize (stmt);
	  sqlite3_reset (stmt);
	}

      errmsg = sqlite_prepare_errdata (ret, sdb);
      goto exit;
    }

  /* Bind ? values.  */
  if (!NILP (values))
    {
      const char *err = bind_values (sdb, stmt, values);
      if (err != NULL)
	{
	  errmsg = build_string (err);
	  goto exit;
	}
    }

  ret = sqlite3_step (stmt);

  if (ret == SQLITE_ROW)
    {
      Lisp_Object data = Qnil;
      do
	data = Fcons (row_to_value (stmt), data);
      while (sqlite3_step (stmt) == SQLITE_ROW);

      sqlite3_finalize (stmt);
      return Fnreverse (data);
    }
  else if (ret == SQLITE_OK || ret == SQLITE_DONE)
    {
      Lisp_Object rows = make_fixnum (sqlite3_changes (sdb));
      sqlite3_finalize (stmt);
      return rows;
    }
  else
    errmsg = build_string (sqlite3_errmsg (sdb));

 exit:
  sqlite3_finalize (stmt);
  xsignal1 (ret == SQLITE_LOCKED || ret == SQLITE_BUSY?
	    Qsqlite_locked_error: Qsqlite_error,
	    errmsg);
}