1;;;
2;;; Tools to handle MySQL connection and querying
3;;;
4
5(in-package :pgloader.source.mysql)
6
7(defvar *connection* nil "Current MySQL connection")
8
9;;;
10;;; General utility to manage MySQL connection
11;;;
12(defclass mysql-connection (db-connection)
13  ((use-ssl :initarg :use-ssl :accessor myconn-use-ssl)))
14
15(defmethod initialize-instance :after ((myconn mysql-connection) &key)
16  "Assign the type slot to mysql."
17  (setf (slot-value myconn 'type) "mysql"))
18
19(defmethod clone-connection ((c mysql-connection))
20  (let ((clone
21         (change-class (call-next-method c) 'mysql-connection)))
22    (setf (myconn-use-ssl clone) (myconn-use-ssl c))
23    clone))
24
25(defmethod ssl-mode ((myconn mysql-connection))
26  "Return non-nil when the connection uses SSL"
27  (ecase (myconn-use-ssl myconn)
28    (:try  :unspecified)
29    (:yes  t)
30    (:no   nil)))
31
32(defmethod open-connection ((myconn mysql-connection) &key)
33  (setf (conn-handle myconn)
34        (if (and (consp (db-host myconn)) (eq :unix (car (db-host myconn))))
35            (qmynd:mysql-local-connect :path (cdr (db-host myconn))
36                                       :username (db-user myconn)
37                                       :password (db-pass myconn)
38                                       :database (db-name myconn))
39            (qmynd:mysql-connect :host (db-host myconn)
40                                 :port (db-port myconn)
41                                 :username (db-user myconn)
42                                 :password (db-pass myconn)
43                                 :database (db-name myconn)
44                                 :ssl (ssl-mode myconn))))
45  (log-message :debug "CONNECTED TO ~a" myconn)
46
47  ;; apply mysql-settings, if any
48  (loop :for (name . value) :in *mysql-settings*
49     :for sql := (format nil "set ~a = ~a;" name value)
50     :do (query myconn sql))
51  ;; return the connection object
52  myconn)
53
54(defmethod close-connection ((myconn mysql-connection))
55  (qmynd:mysql-disconnect (conn-handle myconn))
56  (setf (conn-handle myconn) nil)
57  myconn)
58
59(defmethod query ((myconn mysql-connection)
60                  sql
61                  &key
62                    row-fn
63                    (as-text t)
64                    (result-type 'list))
65  "Run SQL query against MySQL connection MYCONN."
66  (log-message :sql "MySQL: sending query: ~a" sql)
67  (qmynd:mysql-query (conn-handle myconn)
68                     sql
69                     :row-fn row-fn
70                     :as-text as-text
71                     :result-type result-type))
72
73;;;
74;;; The generic API query is recent, used to look like this:
75;;;
76(declaim (inline mysql-query))
77(defun mysql-query (query &key row-fn (as-text t) (result-type 'list))
78  "Execute given QUERY within the current *connection*, and set proper
79   defaults for pgloader."
80  (query *connection* query
81         :row-fn row-fn
82         :as-text as-text
83         :result-type result-type))
84
85