Fork me on GitHub
#sql
<
2019-04-25
>
luskwater17:04:06

@seancorfield (or others): is there a best-way (simply explained) of turning a DatabaseMetaData ResultSet into the appropriate vector of maps? I’m trying to pull a table’s column-metadata in order to turn it into a skeleton GraphQL query, for what that’s worth.

gklijs18:04:45

Sounds interesting, a bit like hasura? https://github.com/hasura/graphql-engine

luskwater18:04:23

No, more a bit like “gee, I never do anything straightaway, and it would be cool to learn something about GraphQL while I work on this antique Rails app, and since I write all my tools using parentheses anyway…”

hiredman17:04:35

resultset-seq

luskwater18:04:07

Ah, yes, was going to fall back to that (I’ve used it many times before)

gklijs19:04:59

Came across this, might be interesting, although I have my doubts his useful reactive really is. https://speakerdeck.com/mp911de/reactive-relational-database-connectivity?slide=34

ikitommi23:04:31

@seancorfield did a quick test with the new :builder-fn. Normal usage is now bit slower as there is the new extra option passing, but it now allows a cached ->row function to be used. Some numbers (updated to porsas readme) too.

ikitommi23:04:59

• few hunded nanos extra to the normal case (4000ns) • using cached compiled mapper is 1500ns

ikitommi23:04:50

the impl for fast the :builder looks like:

(defn caching-row-builder
  ([]
   (caching-row-builder (p/qualified-key)))
  ([key]
   (let [cache (HashMap.)] ;; TODO: make bounded
     (fn [^ResultSet rs opts]
       (let [sql (:next.jdbc/sql-string opts)
             ->row (or (.get cache sql)
                       (let [cols (#'p/col-map rs key)
                             ->row (#'p/rs-> nil (map second cols))]
                         (.put cache sql ->row)
                         ->row))]
         (reify
           rs/RowBuilder
           (->row [_] (->row rs))
           (with-column [_ row _] row)
           (column-count [_] 0)
           (row! [_ row] row)
           rs/ResultSetBuilder
           (->rs [_] (transient []))
           (with-row [_ rs row] (conj! rs row))
           (rs! [_ rs] (persistent! rs))))))))

;; define once, contains cache of ResultSet->EDN functions
(def caching-builder (caching-row-builder))

(bench! (jdbc/execute! connection ["SELECT * FROM fruit"] {:builder-fn caching-row-builder}))

ikitommi23:04:23

the cache is naive, should be bounded (and inspectable), there are some good existing ones in Java libs.