|
14 | 14 | [hasch.core :as hasch] |
15 | 15 | [clojure.string :as str]) |
16 | 16 | (:import [java.sql Blob] |
17 | | - [com.mchange.v2.c3p0 ComboPooledDataSource PooledDataSource] |
| 17 | + [com.mchange.v2.c3p0 ComboPooledDataSource PooledDataSource] |
18 | 18 | (java.io ByteArrayInputStream) |
19 | 19 | (java.sql Connection))) |
20 | 20 |
|
|
30 | 30 | ;; each unique spec will have its own pool |
31 | 31 | (defn- pool-key [db-spec] |
32 | 32 | (keyword |
33 | | - (str (hasch/uuid (select-keys db-spec [:dbtype :jdbcUrl :host :port :user :password :dbname :sync?]))))) |
| 33 | + (str (hasch/uuid (select-keys db-spec [:dbtype :jdbcUrl :host :port :user :password :dbname :sync?]))))) |
34 | 34 |
|
35 | 35 | (defn get-connection [db-spec] |
36 | 36 | (let [id (pool-key db-spec) |
37 | 37 | conn (get @pool id)] |
38 | | - (if-not (nil? conn) |
| 38 | + (if-not (nil? conn) |
39 | 39 | conn |
40 | 40 | (let [conns ^PooledDataSource (connection/->pool ComboPooledDataSource db-spec) |
41 | | - shutdown (fn [] (.close ^PooledDataSource conns))] |
| 41 | + shutdown (fn [] (.close ^PooledDataSource conns))] |
42 | 42 | (swap! pool assoc id conns) |
43 | 43 | (.close (jdbc/get-connection conns)) |
44 | | - (.addShutdownHook (Runtime/getRuntime) |
45 | | - (Thread. ^Runnable shutdown)) |
| 44 | + (.addShutdownHook (Runtime/getRuntime) |
| 45 | + (Thread. ^Runnable shutdown)) |
46 | 46 | conns)))) |
47 | 47 |
|
48 | 48 | (defn remove-from-pool [db-spec] |
|
222 | 222 | (if (:sync? env) nil (go-try- nil))) |
223 | 223 | (-create-store [_ env] |
224 | 224 | (async+sync (:sync? env) *default-sync-translation* |
225 | | - (go-try- |
| 225 | + (go-try- |
226 | 226 | ;; Using CREATE IF NOT EXISTS is regarded as a schema change. To allow the store to be used |
227 | 227 | ;; where schema changes are not allowed on production e.g. planetscale or the user does have schema permissions, |
228 | 228 | ;; we test for existence first. This triggers an exception if it doesn't exist which we catch. |
229 | 229 | ;; Testing for existence in other ways is not worth the effort as it is specific to the db setup |
230 | 230 | ;; not just the type |
231 | | - (let [res (try |
232 | | - (jdbc/execute! connection [(str "select 1 from " table " limit 1")]) |
233 | | - (catch Exception _e |
234 | | - (debug (str "Table " table " does not exist. Attempting to create it.")) |
235 | | - nil))] |
236 | | - (when (nil? res) |
237 | | - (jdbc/execute! connection (create-statement (:dbtype db-spec) table))))))) |
| 231 | + (let [res (try |
| 232 | + (jdbc/execute! connection [(str "select 1 from " table " limit 1")]) |
| 233 | + (catch Exception _e |
| 234 | + (debug (str "Table " table " does not exist. Attempting to create it.")) |
| 235 | + nil))] |
| 236 | + (when (nil? res) |
| 237 | + (jdbc/execute! connection (create-statement (:dbtype db-spec) table))))))) |
238 | 238 | (-sync-store [_ env] |
239 | 239 | (if (:sync? env) nil (go-try- nil))) |
240 | 240 | (-delete-store [_ env] |
|
257 | 257 | (let [old-url (:jdbcUrl db) |
258 | 258 | spec (connection/uri->db-spec old-url) ;; set port to -1 if none is in the url |
259 | 259 | port (:port spec) |
260 | | - new-spec (-> spec |
| 260 | + new-spec (-> spec |
261 | 261 | (update :dbtype #(str/replace % #"postgres$" "postgresql")) ;the postgres driver does not support long blob |
262 | | - (assoc :port (if (pos? port) |
263 | | - port |
264 | | - (-> connection/dbtypes |
265 | | - (get (:dbtype spec)) |
266 | | - :port))))] |
| 262 | + (assoc :port (if (pos? port) |
| 263 | + port |
| 264 | + (-> connection/dbtypes |
| 265 | + (get (:dbtype spec)) |
| 266 | + :port))))] |
267 | 267 | new-spec))) |
268 | 268 |
|
269 | 269 | (defn connect-store [db-spec & {:keys [table opts] |
270 | 270 | :or {table default-table} |
271 | 271 | :as params}] |
272 | | - (let [db-spec (prepare-spec db-spec)] |
| 272 | + (let [db-spec (prepare-spec db-spec)] |
273 | 273 | (when-not (:dbtype db-spec) |
274 | | - (throw (ex-info ":dbtype must be explicitly declared" {:options dbtypes}))) |
275 | | - |
| 274 | + (throw (ex-info ":dbtype must be explicitly declared" {:options dbtypes}))) |
| 275 | + |
276 | 276 | (when-not (supported-dbtypes (:dbtype db-spec)) |
277 | 277 | (warn "Unsupported database type " (:dbtype db-spec) |
278 | 278 | " - full functionality of store is only guaranteed for following database types: " supported-dbtypes)) |
279 | 279 |
|
280 | | - (System/setProperties |
281 | | - (doto (java.util.Properties. (System/getProperties)) |
282 | | - (.put "com.mchange.v2.log.MLog" "com.mchange.v2.log.slf4j.Slf4jMLog"))) ;; using Slf4j allows timbre to control logs. |
283 | | - |
| 280 | + (System/setProperties |
| 281 | + (doto (java.util.Properties. (System/getProperties)) |
| 282 | + (.put "com.mchange.v2.log.MLog" "com.mchange.v2.log.slf4j.Slf4jMLog"))) ;; using Slf4j allows timbre to control logs. |
| 283 | + |
284 | 284 | (let [complete-opts (merge {:sync? true} opts) |
285 | 285 | db-spec (if (:dbtype db-spec) |
286 | 286 | db-spec |
|
289 | 289 | ^PooledDataSource connection (get-connection db-spec) |
290 | 290 | backing (JDBCTable. db-spec connection table) |
291 | 291 | config (merge {:opts complete-opts |
292 | | - :config {:sync-blob? true |
| 292 | + :config {:sync-blob? true |
293 | 293 | :in-place? true |
294 | 294 | :lock-blob? true} |
295 | | - :default-serializer :FressianSerializer |
296 | | - :compressor null-compressor |
297 | | - :encryptor null-encryptor |
298 | | - :buffer-size (* 1024 1024)} |
| 295 | + :default-serializer :FressianSerializer |
| 296 | + :compressor null-compressor |
| 297 | + :encryptor null-encryptor |
| 298 | + :buffer-size (* 1024 1024)} |
299 | 299 | (dissoc params :opts :config))] |
300 | 300 | (connect-default-store backing config)))) |
301 | 301 |
|
302 | 302 | (defn release |
303 | 303 | "Must be called after work on database has finished in order to close connection" |
304 | 304 | [store env] |
305 | 305 | (async+sync (:sync? env) *default-sync-translation* |
306 | | - (go-try- |
307 | | - (.close ^PooledDataSource (:connection ^JDBCTable (:backing store))) |
308 | | - (remove-from-pool (:db-spec ^JDBCTable (:backing store)))))) |
| 306 | + (go-try- |
| 307 | + (.close ^PooledDataSource (:connection ^JDBCTable (:backing store))) |
| 308 | + (remove-from-pool (:db-spec ^JDBCTable (:backing store)))))) |
309 | 309 |
|
310 | 310 | (defn delete-store [db-spec & {:keys [table opts] :or {table default-table}}] |
311 | 311 | (let [complete-opts (merge {:sync? true} opts) |
|
0 commit comments