annotate base/database/database-connect.lisp @ 253:b5ffec94ae6d

some very sketchy Charm constituent code
author Jamie Forth <j.forth@gold.ac.uk>
date Thu, 24 Feb 2011 11:23:18 +0000
parents 6a3adca16910
children
rev   line source
j@191 1 (cl:in-package #:amuse-database-admin)
j@191 2
j@216 3 (defvar *amuse-database* nil
j@216 4 "The default AMuSE-wide database connection is assigned to this
j@216 5 variable. If for any reason, such as testing database interaction,
j@216 6 you do not wish to use the default database, this variable can be
j@216 7 shadowed locally within a particular backend package. For this to
j@216 8 actually work consistantly, all clsql database functions should
j@216 9 specify *amuse-database* explicitally as the :database argument. Not
j@216 10 doing this relies on the value of clsql:*default-database* being the
j@216 11 connection to the correct database, which in most cases will
j@216 12 actually be fine so long as you are not connecting to different
j@216 13 databases.")
j@191 14
j@191 15 (defun connect-to-database (&key (database-name "amuse") username
j@191 16 use-tunnel (make-default t))
j@191 17 "Well, slightly more secure I guess. Requires that an option file
j@191 18 exists containing connection-spec s-expressions. If no such file
j@191 19 exists a skeleton file can be created by calling
j@191 20 make-db-option-file (the password still needs to be added
j@191 21 manually). The path is ~/.amuse.lisp.
j@191 22
j@191 23 A better approach might be to use something like:
j@191 24 http://www.cliki.net/trivial-configuration-parser. Or for slime to
j@191 25 prompt the user for the password something
j@191 26 like (swank::eval-in-emacs `(read-passwd \"Password: \")). However,
j@191 27 this presents other security issues.
j@191 28
j@191 29 If use-tunnel is t, then regardless of the host specified in the
j@191 30 connection-spec, it will be set to localhost. It is assumed that the
j@191 31 tunnel is already set up.
j@191 32
j@191 33 When make-default is t, the newly created connection is assigned to
j@191 34 *amuse-database*. If make-default is nil, then the connection is
j@191 35 returned and is expected to be handled by the caller. This is useful
j@191 36 for connecting to different databases within individual
j@191 37 implementations (mainly for testing purposes)."
j@191 38 (if (and make-default
j@191 39 *amuse-database*
j@191 40 (clsql-mysql::is-database-open *amuse-database*))
j@191 41 (error "A default AMuSE database connection already exists:
j@191 42 ~S" (clsql:database-name *amuse-database*))
j@191 43 (let ((connection-spec (%get-connection-spec database-name
j@191 44 username)))
j@191 45 (when use-tunnel
j@191 46 (setf (car connection-spec) "127.0.0.1"))
j@191 47 (let ((connection (%get-database-connection connection-spec)))
j@191 48 (when make-default
j@191 49 (setf *amuse-database* connection))
j@191 50 connection))))
j@191 51
j@191 52 (defun disconnect-from-database (&optional (database-connection
j@191 53 *amuse-database*))
j@191 54 (clsql:disconnect :database database-connection))
j@191 55
j@191 56 (defun make-db-option-file (&key database-name host username (port "3306"))
j@191 57 (with-open-file (stream (%make-db-option-file-pathname) :direction :output)
j@191 58 (sb-ext:run-program "chmod"
j@191 59 (list "600" (namestring
j@191 60 (%make-db-option-file-pathname)))
j@191 61 :search t)
j@191 62 (princ "
j@191 63 ;;; Option file containing connection-spec s-expressions for connecting
j@191 64 ;;; to a database from within AMuSE. You can have multiple specifications,
j@191 65 ;;; but they must be uniquely identifiable by database name or a combination
j@191 66 ;;; of database and username.
j@191 67
j@191 68 ;;; You need to fill in the missing <details>." stream)
j@191 69 (format stream "~2%(~S ~S ~S \"<pwd>\" ~S)"
j@191 70 (if host host "<host>")
j@191 71 (if database-name database-name "<db-name>")
j@191 72 (if username username "<username>")
j@191 73 port))
j@191 74 (warn "You now need to manually edit ~A."
j@191 75 (namestring (%make-db-option-file-pathname))))
j@191 76
j@251 77
j@251 78 ;;;=====================================================================
j@191 79 ;;; Helper functions
j@251 80 ;;;=====================================================================
j@191 81
j@191 82 (defun %get-database-connection (connection-spec)
j@191 83 (clsql:connect connection-spec
j@191 84 :if-exists :old
j@191 85 :database-type :mysql))
j@191 86
j@191 87 (defun %get-connection-spec (db-name username)
j@191 88 (let ((option-file (probe-file (%make-db-option-file-pathname))))
j@191 89 (if option-file
j@191 90 (with-open-file (stream option-file)
j@191 91 (loop for connection-spec = (read stream nil)
j@191 92 while connection-spec
j@191 93 do (destructuring-bind (host db usr pwd prt)
j@191 94 connection-spec
j@191 95 (declare (ignore host pwd prt))
j@191 96 (when (equal db-name db)
j@191 97 (when (or (null username)
j@191 98 (equal username usr))
j@191 99 (return connection-spec))))
j@191 100 finally (error "No connection-spec exists matching
j@191 101 database: ~A and username: ~A" db-name username)))
j@191 102 ;; If file doesn't exist, create it.
j@191 103 (error "~A option file does not exist.
j@191 104 You need to run: amuse-database-admin:make-db-option-file."
j@191 105 (namestring (%make-db-option-file-pathname))))))
j@191 106
j@191 107 (defun %make-db-option-file-pathname ()
j@191 108 (merge-pathnames (user-homedir-pathname) ".amuse.lisp"))