Search code examples
clojuredatomic

Datomic not a valid :uri for attribute


I'm trying to insert a value on an attribute defined as

{:db/ident       :foo/uri
 :db/valueType   :db.type/uri
 :db/cardinality :db.cardinality/one
 :db/doc         "Test attribute of value type uri."}

I'm inserting

{:foo/uri "scheme://host/path"}

and get

Execution error (ExceptionInfo) at datomic.client.api.async/ares (async.clj:58).
Value scheme://host/path is not a valid :uri for attribute :foo/uri

I'm lost as to what to insert here. It should be a string, right? No reader literal?

I found zero examples of this online. Also took a look at the java class corresponding to this but no illumination. Or maybe it needs an instance of java.net.URI, so to put it in edn we'd need to install our own reader literal?


Solution

  • It does need to be an instance of java.net.URI.

    If it's part of your code, you could wrap it up when creating it:

    {:foo/uri (new java.net.URI "scheme://host/path")}
    

    If you want to read it in from an edn file, then you could use a custom tag, say #URI, in the file and pass a custom reader function as an option to edn/read-string:

    ;;; in some file located at `path`
    {:foo/uri #URI"scheme://host/path"}
    
    ;;; code to read the file at `path`
    (require '[clojure.edn :as edn])
    (-> path
        slurp
        (edn/read-string {:readers {'URI #(new java.net.URI %)}})
    

    You could also do this with clojure.tools.reader, which allows for unsafe code execution (so probably not recommended):

    ;;; use reader tools
    (require '[clojure.tools.reader :as r])
    (r/read-string "{:foo/uri #=(new java.net.URI \"scheme://host/path\")}")