-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a97b69e
commit bf9efe1
Showing
8 changed files
with
202 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/bash | ||
docker-compose -f docker-compose.yml up mysql --no-start | ||
docker-compose -f docker-compose.yml start mysql | ||
docker ps |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
#!/bin/bash | ||
docker-compose -f docker-compose.yml up --no-start | ||
docker-compose -f docker-compose.yml start | ||
docker-compose -f docker-compose.yml up postgres --no-start | ||
docker-compose -f docker-compose.yml start postgres | ||
docker ps |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,180 @@ | ||
(ns xiana.db.client.mysql) | ||
(ns xiana.db.client.mysql | ||
(:require [xiana.db.protocol :as db-protocol] | ||
[clj-test-containers.core :as tc] | ||
[next.jdbc :as jdbc] | ||
[hikari-cp.core :as hcp] | ||
[honeysql.core :as sql] | ||
[xiana.db.migrate :as migr]) | ||
(:import (java.sql | ||
Connection) | ||
(java.lang | ||
AutoCloseable))) | ||
|
||
(def default-opts {:return-keys true}) | ||
|
||
(defn get-pool-datasource | ||
[{:xiana/keys [hikari-pool-params mysql]}] | ||
(when (and hikari-pool-params mysql) | ||
(fn [{:keys [port dbname host dbtype user password]}] | ||
(hcp/make-datasource | ||
(merge {:adapter dbtype | ||
:username user | ||
:password password | ||
:database-name dbname | ||
:server-name host | ||
:port-number port} | ||
hikari-pool-params))))) | ||
|
||
(defn get-datasource | ||
([config] | ||
(get-datasource config 0)) | ||
([config count] | ||
(let [create-datasource (or (:xiana/create-custom-datasource config) | ||
(get-pool-datasource config) | ||
jdbc/get-datasource) | ||
jdbc-opts (merge default-opts | ||
(:xiana/jdbc-opts config))] | ||
(try (-> config | ||
create-datasource | ||
(jdbc/with-options jdbc-opts)) | ||
(catch Exception e (if (< count 10) | ||
(get-datasource config (inc count)) | ||
(throw e))))))) | ||
|
||
(defn docker-mysql! | ||
[{mysql-config :xiana/mysql :as config}] | ||
(let [{:keys [dbname user password image-name]} mysql-config | ||
container (tc/start! | ||
(tc/create | ||
{:image-name image-name | ||
:exposed-ports [5432] | ||
:env-vars {"MYSQL_DB" dbname | ||
"MYSQL_USER" user | ||
"MYSQL_PASSWORD" password}})) | ||
|
||
port (get (:mapped-ports container) 5432) | ||
mysql-config (assoc | ||
mysql-config | ||
:port port | ||
:embedded container | ||
:subname (str "//localhost:" port "/" dbname))] | ||
(tc/wait {:wait-strategy :log | ||
:message "accept connections"} (:container container)) | ||
(assoc config :xiana/mysql mysql-config))) | ||
|
||
(defn migrate! | ||
([config] | ||
(migrate! config 0)) | ||
([config count] | ||
(try | ||
(migr/migrate (migr/get-db-config config)) | ||
(catch Exception e (if (< count 10) | ||
(migrate! config (inc count)) | ||
(throw e)))) | ||
config)) | ||
|
||
(defn connect | ||
"Adds `:datasource` key to the `:xiana/mysql` config section | ||
and duplicates `:xiana/mysql` under the top-level `:db` key." | ||
[{mysql-config :xiana/mysql :as config}] | ||
(let [new-mysql-config (assoc-in mysql-config [:config :datasource] (get-datasource (:config mysql-config)))] | ||
(assoc config | ||
:xiana/mysql (:config new-mysql-config) | ||
:db (:config new-mysql-config)))) | ||
|
||
(defn ->sql-params | ||
"Parse sql-map using honeysql format function with pre-defined | ||
options that target mysql." | ||
[sql-map] | ||
(sql/format sql-map | ||
{:quoting :ansi | ||
:parameterizer :mysql | ||
:return-param-names false})) | ||
|
||
(defn execute | ||
"Gets datasource, parse the given sql-map (query) and | ||
execute it using `jdbc/execute!`, and returns the modified keys" | ||
[datasource sql-map] | ||
(let [sql-params (->sql-params sql-map)] | ||
(jdbc/execute! datasource sql-params default-opts))) | ||
|
||
(defn in-transaction | ||
([tx sql-map] | ||
(in-transaction tx sql-map nil)) | ||
([tx sql-map jdbc-opts] | ||
{:pre [(instance? Connection tx)]} | ||
(let [sql-params (->sql-params sql-map)] | ||
(jdbc/execute! tx sql-params (merge default-opts jdbc-opts))))) | ||
|
||
(defn multi-execute! | ||
[datasource {:keys [queries transaction?]}] | ||
(if transaction? | ||
(jdbc/with-transaction | ||
[tx datasource] | ||
(mapv #(in-transaction tx % (:options datasource)) queries)) | ||
(mapv #(execute datasource %) queries))) | ||
|
||
(defrecord MySQLDB [config jdbc-opts embedded] | ||
db-protocol/DatabaseP | ||
|
||
(define-container [_this] | ||
(docker-mysql! config)) | ||
|
||
(define-migration [_this] | ||
(migrate! config)) | ||
|
||
(define-migration [_this count] | ||
(migrate! config count)) | ||
|
||
(connect [_this] | ||
(let [new-config {:xiana/mysql config | ||
:xiana/jdbc-opts jdbc-opts}] | ||
(connect new-config))) | ||
|
||
(define-parameters [_this sql-map] | ||
(->sql-params sql-map)) | ||
|
||
(execute [this sql-map] | ||
(let [ds (get-in this [:config :datasource])] | ||
(execute ds sql-map))) | ||
|
||
(in-transaction [_this tx sql-map] | ||
(in-transaction tx sql-map)) | ||
|
||
(multi-execute [this query-map] | ||
(let [ds (get-in this [:config :datasource])] | ||
(multi-execute! ds query-map))) | ||
|
||
AutoCloseable | ||
(close [this] | ||
(when-let [emb (embedded this)] | ||
(.close emb)))) | ||
|
||
(def db-access | ||
"Database access interceptor, works from `:query` and from `db-queries` keys | ||
Enter: nil. | ||
Leave: Fetch and execute a given query using the chosen database | ||
driver, if succeeds associate its results into state response data. | ||
Remember the entry query must be a sql-map, e.g: | ||
{:select [:*] :from [:users]}." | ||
{:leave | ||
(fn [{query-or-fn :query | ||
db-queries :db-queries | ||
:as state}] | ||
(let [datasource (get-in state [:deps :db :datasource]) | ||
query (cond | ||
(fn? query-or-fn) (query-or-fn state) | ||
:else query-or-fn) | ||
db-data (cond-> [] | ||
query (into (execute datasource query)) | ||
db-queries (into (multi-execute! datasource db-queries)) | ||
:always seq)] | ||
(assoc-in state [:response-data :db-data] db-data))) | ||
:error | ||
(fn [state] | ||
(merge state | ||
{:response {:status 500 | ||
:body (pr-str (:error state))}}))}) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
(ns xiana.db-provisional | ||
(:require [xiana.db.client.postgres :as pg])) | ||
(:require [xiana.db.client.postgres :as pg] | ||
[xiana.db.client.mysql :as mysql])) | ||
|
||
(def dbms-map {:xiana/postgresql pg/->PostgresDB}) | ||
(def dbms-map {:xiana/postgresql pg/->PostgresDB | ||
:xiana/mysql mysql/->MySQLDB}) | ||
|