Skip to content

ljos/sparql-mode

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

What is it?

A major mode for emacs that provides syntax highlighting for SPARQL. It also provides a way to execute queries against a SPARQL HTTP endpoint, such as is provided by Fuseki. It is also possible to query other endpoints like DBPedia.

Getting Started

https://melpa.org/packages/sparql-mode-badge.svg https://stable.melpa.org/packages/sparql-mode-badge.svg

  • Download sparql-mode and put it in a directory somewhere.
  • Add the following to your .emacs file
(add-to-list 'load-path "/path/to/sparql-mode-dir")
(autoload 'sparql-mode "sparql-mode.el"
    "Major mode for editing SPARQL files" t)
(add-to-list 'auto-mode-alist '("\\.sparql$" . sparql-mode))
(add-to-list 'auto-mode-alist '("\\.rq$" . sparql-mode))

Now sparql-mode will load whenever you visit a file whose name ends with .sparql. Alternatively, run M-x sparql-mode in an existing buffer containing SPARQL commands.

It is also possible to add

-*- mode: sparql -*-

to the top of the file. This is a comment read by emacs to discover what mode to use.

Auto complete

SPARQL-mode has basic support for both auto-complete-mode and company-mode. Just add your favourite completion mode to sparql-mode-hook.

(add-hook 'sparql-mode-hook 'your-favourite-completion-mode)

Executing SPARQL Queries from within Emacs

From a buffer that is in sparql-mode, execute M-x sparql-query-region. You will be prompted for a SPARQL HTTP endpoint in the minibuffer, which defaults to http://localhost:2020/. Once set, it will be used for all subsequent queries in that buffer. Results will be displayed in another buffer in CSV format.

Org-babel support

It is also possible to use sparql-mode with org-mode and executing queries with org-babel. You can do that by adding the following snippet or adding (sparql . t) to languages org-babel can load:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((sparql . t)))

You can then execute the query by pressing C-c C-c on the source-block header.

By default results formatted as text/csv will be converted to an org table. This can be disabled by adding :results scalar to the header. See examples.

Example

Default behaviour for results in csv is to convert the result to a table:

#+BEGIN_SRC sparql :url https://live.dbpedia.org/sparql :format text/csv
  SELECT DISTINCT ?Concept WHERE {
    [] a ?Concept
  } LIMIT 5
#+END_SRC

#+RESULTS:
| Concept                                                          |
|------------------------------------------------------------------|
| http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat          |
| http://www.openlinksw.com/schemas/virtrdf#QuadStorage            |
| http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat |
| http://www.openlinksw.com/schemas/virtrdf#QuadMap                |
| http://www.openlinksw.com/schemas/virtrdf#QuadMapValue           |

If you don’t want to convert the result to a table, you can override that behaviour by specifying that the result should be scalar:

#+HEADER: :url https://live.dbpedia.org/sparql
#+HEADER: :format text/csv
#+HEADER: :results scalar
#+BEGIN_SRC sparql
  SELECT DISTINCT ?Concept WHERE {
    [] a ?Concept
  } LIMIT 5
#+END_SRC

#+RESULTS:
: "Concept"
: "http://www.openlinksw.com/schemas/virtrdf#QuadMapFormat"
: "http://www.openlinksw.com/schemas/virtrdf#QuadStorage"
: "http://www.openlinksw.com/schemas/virtrdf#array-of-QuadMapFormat"
: "http://www.openlinksw.com/schemas/virtrdf#QuadMap"
: "http://www.openlinksw.com/schemas/virtrdf#QuadMapValue"

We can also declare variables that will then be expanded before execution. For example the following query:

SELECT * WHERE {
  ?x foaf:name ?name.
  $x foaf:email ?email.
}

will be transformed into the following before it is executed:

SELECT * WHERE {
  friend:Julia foaf:name ?name.
  friend:Julia foaf:email ?email.
}

Notice that $x and ?x are treated as identical. This is because SPARQL treats them as identical.

By combining this with the #+call syntax we can create and reuse queries:

#+NAME: count-statements-in-graph
#+BEGIN_SRC sparql :var graph="<>"
  SELECT (COUNT(*) AS ?count) WHERE {
    GRAPH $graph {
      ?s ?p ?o .
    }
  }
#+END_SRC

#+CALL: count-statements-in-graph("<http://example.com/my-graph>")

#+RESULTS:
| count |
|-------|
|  1001 |


#+CALL: count-statements-in-graph("<http://example.com/my-other-graph>")

#+RESULTS:
| count |
|-------|
|   100 |

Notice that the server request is done synchronously and will therefore lock the editor if the request takes a long time.

Bugs and Enhancements

If you have a problem or would like to see it get better in a specific way, feel free to drop an issue in the issue tracker. Enjoy!