;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; Package: umlisp -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sql.lisp ;;;; Purpose: Low-level SQL routines data for UMLisp ;;;; Author: Kevin M. Rosenberg ;;;; Created: Apr 2000 ;;;; ;;;; This file, part of UMLisp, is ;;;; Copyright (c) 2000-2012 by Kevin M. Rosenberg, M.D. ;;;; ;;;; UMLisp users are granted the rights to distribute and use this software ;;;; as governed by the terms of the GNU General Public License. ;;;; ************************************************************************* (in-package #:umlisp) (defparameter +umls-sql-map+ '((:2004aa . "KUMLS2004AA") (:2006ac . "KUMLS2006AC") (:2006ad . "MTS2006AD") (:2009ab . "MTS2009AB") (:2010aa . "MTS2010AA") (:2012ab_all . "MTS2012AB_ALL") (:2020ab_all . "MTS2020AB_ALL"))) (defvar +default-umls-db+ "MTS2020AB_ALL") (defun lookup-db-name (db) (cdr (assoc (ensure-keyword db) +umls-sql-map+))) (defvar *umls-sql-db* +default-umls-db+) (defun umls-sql-db () *umls-sql-db*) (defun set-umls-sql-db (db) (etypecase db (string (setq *umls-sql-db* db)) (keyword (setq *umls-sql-db* (lookup-db-name db))))) (defvar *umls-sql-user* "mts") (defun umls-sql-user () *umls-sql-user*) (defun set-umls-sql-user (u) (sql-disconnect-pooled) (setq *umls-sql-user* u)) (defvar *umls-sql-passwd* "_mts") (defun umls-sql-passwd () *umls-sql-passwd*) (defun set-umls-sql-passwd (p) (sql-disconnect-pooled) (setq *umls-sql-passwd* p)) (defvar *umls-sql-host* "mysql.med-info.com") (defun umls-sql-host () *umls-sql-host*) (defun set-umls-sql-host (h) (sql-disconnect-pooled) (setq *umls-sql-host* h)) (defvar *umls-sql-type* :mysql) (defun umls-sql-type () *umls-sql-type*) (defun set-umls-sql-type (h) (sql-disconnect-pooled) (setq *umls-sql-type* h)) (defun umls-connection-spec () (if (eql *umls-sql-type* :mysql) (list *umls-sql-host* *umls-sql-db* *umls-sql-user* *umls-sql-passwd* nil '((:local-infile . 1)) ) (list *umls-sql-host* *umls-sql-db* *umls-sql-user* *umls-sql-passwd*))) (defun sql-connect () "Connect to UMLS database, automatically used pooled connections" (let ((db (clsql:connect (umls-connection-spec) :database-type *umls-sql-type* :encoding :utf-8 :pool t))) db)) (defun sql-disconnect (conn) "Disconnect from UMLS database, but put connection back into pool" (clsql:disconnect :database conn)) (defun sql-disconnect-pooled () (clsql:disconnect-pooled)) (defmacro with-sql-connection ((conn) &body body) `(let ((,conn (sql-connect))) (unwind-protect (progn ,@body) (when ,conn (clsql:disconnect :database ,conn))))) (defun sql-query (cmd conn &key (result-types :auto)) (clsql:query cmd :database conn :result-types result-types :field-names nil)) (defun sql-execute (cmd conn) (clsql:execute-command cmd :database conn)) (defun sql (stmt conn) (if (string-equal "SELECT" (subseq stmt 0 6)) (sql-query stmt conn) (sql-execute stmt conn))) (defun umls-sql (stmt) (check-type stmt string) (with-sql-connection (conn) (sql stmt conn))) ;;; Pool of open connections (defmacro with-mutex-sql ((conn) &body body) `(let ((,conn (sql-connect))) (unwind-protect (progn ,@body) (when ,conn (sql-disconnect ,conn))))) (defun mutex-sql-execute (cmd) (with-mutex-sql (conn) (sql-execute cmd conn))) (defun mutex-sql-query (cmd &key (result-types :auto)) (with-mutex-sql (conn) (sql-query cmd conn :result-types result-types)))