En théorie, vous pouvez utiliser l'une des méthodes de clojure.contrib.sql/Insérer- * pour insérer un blob, en passant le blob soit comme un tableau d'octets, ou un java.sql.Blob java.io Objet .InputStream. En pratique, il dépend du conducteur.
Pour de nombreuses implémentations JDBC, tout ce qui précède fonctionne comme prévu, mais si vous utilisez sqlitejdbc 0.5.6 à partir de Clojars, vous trouverez votre blob converti en une chaîne via toString(). Toutes les commandes clojure.contrib.sql/insert- * sont émises via clojure.contrib.sql/do-prepared, qui appelle setObject() sur un java.sql.PreparedStatement. L'implémentation sqlitejdbc ne gère pas setObject() pour l'un des types de données blob, mais par défaut les contraint à une chaîne. Voici une solution qui vous permet de stocker des blobs dans SQLite:
(use '[clojure.contrib.io :only (input-stream to-byte-array)])
(require '[clojure.contrib.sql :as sql])
(defn my-do-prepared
"Executes an (optionally parameterized) SQL prepared statement on the
open database connection. Each param-group is a seq of values for all of
the parameters. This is a modified version of clojure.contrib.sql/do-prepared
with special handling of byte arrays."
[sql & param-groups]
(with-open [stmt (.prepareStatement (sql/connection) sql)]
(doseq [param-group param-groups]
(doseq [[index value] (map vector (iterate inc 1) param-group)]
(if (= (class value) (class (to-byte-array "")))
(.setBytes stmt index value)
(.setObject stmt index value)))
(.addBatch stmt))
(sql/transaction
(seq (.executeBatch stmt)))))
(defn my-load-blob [filename]
(let [blob (to-byte-array (input-stream filename))]
(sql/with-connection db
(my-do-prepared "insert into mytable (blob_column) values (?)" [blob]))))
Cela ne fonctionne pas si je veux enregistrer un fichier en tant que BLOB. – aQ123
Oh. Je n'imagine pas 'FileInputStream' est sérialisable - je me demande si c'est le problème. – harto