Search code examples
clojurehsqldb

update-values not generating an actual update on hsqldb


I'm new to clojure. Have been playing with jdbc using hsqldb.

Did this function to update table "persona" where the field "cedula" is the primary key

(defn update [cedula x]
(sql/with-connection common/database
    (sql/update-values :persona
        ["cedula=?" cedula] x)))

Ran this in REPL

(per/update 111 {:cedula 122 :nombre "Raul" :cargo "mm"})

But after that if I go to the .log file in the DB I see that it does a delete and then an insert.

/*C15*/SET SCHEMA PUBLIC
CONNECT USER SA
SET AUTOCOMMIT FALSE
DELETE FROM PERSONA WHERE CEDULA=111
INSERT INTO PERSONA VALUES(122,'Raul','mm')
COMMIT
SET AUTOCOMMIT TRUE
DISCONNECT

Is that normal?


Solution

  • This is the code for update-values:

    (defn update-values
      "Updates values on selected rows in a table. where-params is a vector
      containing a string providing the (optionally parameterized) selection
      criteria followed by values for any parameters. record is a map from
      strings or keywords (identifying columns) to updated values."
      [table where-params record]
      (let [[where & params] where-params
            column-strs (map as-identifier (keys record))
            columns (apply str (concat (interpose "=?, " column-strs) "=?"))]
        (do-prepared
          (format "UPDATE %s SET %s WHERE %s"
                  (as-identifier table) columns where)
          (concat (vals record) params))))
    

    As you can see, there's absolutely no way it will generate anything but a UPDATE, as it ought to. So what's actually happening?

    From the HSQLDB docs:

    As HyperSQL logs the DDL and DML statements in the .log file, this file can be used to check what is being sent to the database. Note that UPDATE statements are represented by a DELETE followed by an INSERT statement.

    So the HSQLDB log is simply writing a DELETE and INSERT, even though the query being executed is really an UPDATE.