Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 13 additions & 21 deletions clj/jdbc/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
(jdbc/insert! conn :p {:name \"ada\"})
(jdbc/fetch conn [\"select * from p where name = ?\" \"ada\"]))"
(:require [clojure.string :as str]
[db.sqlite :as sqlite]))
[db.sqlite :as sqlite]
[db.pg :as pg]))

;;; dbspec

Expand Down Expand Up @@ -48,10 +49,6 @@

;;; connection

;; the postgres driver is reached through pgfn, defined with the other pg helpers
;; below; connection calls it for the :postgresql branch.
(declare pgfn)

(defn connection
"Open a connection. spec is a uri string (\"sqlite:path\", a bare sqlite
path, or \"postgres://user:pass@host:port/db\") or a dbspec map with
Expand All @@ -69,15 +66,14 @@
:rollback (atom false)
:close (fn [] (sqlite/close h))})
"postgresql"
;; db.pg (and libpq) load lazily — only when a postgres connection is made,
;; so a sqlite-only app never needs libpq present.
(do (require '[db.pg])
(let [h ((pgfn "connect") (pg-uri spec))]
{:vendor :postgresql
:handle h
:depth (atom 0)
:rollback (atom false)
:close (fn [] ((pgfn "close") h))})))))
;; db.pg is statically required so AOT builds include the PostgreSQL
;; implementation. Its FFI bindings resolve libpq symbols lazily on first use.
(let [h (pg/connect (pg-uri spec))]
{:vendor :postgresql
:handle h
:depth (atom 0)
:rollback (atom false)
:close (fn [] (pg/close h))}))))

;;; queries

Expand Down Expand Up @@ -212,12 +208,8 @@
(defn- sqlite-eval [conn sql params]
(sqlite/query (:handle conn) sql params))

;; db.pg is required lazily (only for a postgres connection), so resolve its fns
;; at runtime — a compile-time db.pg/foo reference would be read as a host class.
(defn- pgfn [n] (deref (resolve (symbol "db.pg" n))))

(defn- pg-eval [conn sql params]
((pgfn "exec") (:handle conn) (pg-placeholders sql) params))
(pg/exec (:handle conn) (pg-placeholders sql) params))

(defn fetch
"Run a query (string or sqlvec), return a vector of keyword-keyed row maps."
Expand All @@ -226,7 +218,7 @@
(let [[sql params] (sqlvec q)
rows (case (:vendor conn)
:sqlite (sqlite-eval conn sql params)
:postgresql ((pgfn "all") (:handle conn) (pg-placeholders sql) params))]
:postgresql (pg/all (:handle conn) (pg-placeholders sql) params))]
(if-let [n (:max-rows opts)] (vec (take n rows)) rows))))

(defn fetch-one
Expand All @@ -250,7 +242,7 @@
[conn]
(case (:vendor conn)
:sqlite (sqlite/last-insert-rowid (:handle conn))
:postgresql (:id (first ((pgfn "all") (:handle conn) "select lastval() as id" [])))))
:postgresql (:id (first (pg/all (:handle conn) "select lastval() as id" [])))))

;;; insert! / update! / delete! — the clojure.jdbc convenience surface

Expand Down
Loading