;;; cl-scopes/storage/storage.lisp ;;;; Common layer for SQL storage functionality. (defpackage :scopes/storage (:use :common-lisp) (:export #:*db-config* #:*db-engine* #:make-engine #:make-storage #:db-params #:db #:drop-table)) (in-package :scopes/storage) (defparameter *db-config* nil) (defparameter *db-engine* nil) (defclass db-engine () ((connect :initarg :connect) (params :initarg :params) (config :initarg :config))) (defun make-engine () (make-engine-db (getf *db-config* :db-type) *db-config*)) (defclass storage () ((engine :initarg :engine) (db :reader db) (schema))) (defun make-storage () (let ((st (make-instance 'storage :engine *db-engine*)) (db (funcall (slot-value *db-engine* 'connect)))) (setf (slot-value st 'db) db) st)) (defun db-params (st) (slot-value (slot-value st 'engine) 'params)) (defun drop-table (st tn) (let ((sql (sxql:yield (sxql:drop-table tn :if-exists t)))) (print sql) (dbi:do-sql (db st) sql))) ;; db-driver-specific stuff (defun connect-sqlite (params config) (declare (ignorable params)) (print config) (apply #'dbi:connect-cached (cons :sqlite3 (getf config :connect-args)))) (defun connect-postgres (params config) (declare (ignorable params)) (apply #'dbi:connect (cons :postgres (getf config :connect-args)))) (defvar *db-params* '(:sqlite3 (:connect connect-sqlite :id-type integer :json-type json) :postgres (:connect connect-postgres :id-type bigserial :json-type jsonb))) (defun make-engine-db (db-type config) (let ((params (getf *db-params* db-type))) (make-instance 'db-engine :params params :config config :connect #'(lambda () (funcall (getf params :connect) params config)))))