Function: sqlite-select

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

Signature

(sqlite-select DB QUERY &optional VALUES RETURN-TYPE)

Documentation

Select data from the database DB that matches QUERY.

If VALUES is non-nil, it should be a list or a vector specifying the values that will be interpolated into a parameterized statement.

By default, the return value is a list, whose contents depend on the value of the optional argument RETURN-TYPE.

If RETURN-TYPE is nil or omitted, the function returns a list of rows matching QUERY. If RETURN-TYPE is full, the function returns a list whose first element is the list of column names, and the rest of the elements are the rows matching QUERY. If RETURN-TYPE is set, the function returns a set object that can be queried with functions like sqlite-next etc., in order to get the data.

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 retval = Qnil, errmsg = Qnil,
    encoded = encode_string (query);

  sqlite3_stmt *stmt = NULL;
  int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded),
				&stmt, NULL);
  if (ret != SQLITE_OK)
    {
      if (stmt)
	sqlite3_finalize (stmt);
      errmsg = sqlite_prepare_errdata (ret, sdb);
      goto exit;
    }

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

  /* Return a handle to get the data.  */
  if (EQ (return_type, Qset))
    {
      retval = make_sqlite (true, sdb, stmt, XSQLITE (db)->name);
      goto exit;
    }

  /* Return the data directly.  */
  Lisp_Object data = Qnil;
  while (sqlite3_step (stmt) == SQLITE_ROW)
    data = Fcons (row_to_value (stmt), data);

  if (EQ (return_type, Qfull))
    retval = Fcons (column_names (stmt), Fnreverse (data));
  else
    retval = Fnreverse (data);
  sqlite3_finalize (stmt);

 exit:
  if (! NILP (errmsg))
    xsignal1 (Qsqlite_error, errmsg);

  return retval;
}