Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Effective slots #159

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
90e638b
Removing unnecessary check for col-type presence
daninus14 Oct 31, 2024
9c8e70e
Implementation of effective standard slots for the mito metaclass
daninus14 Oct 31, 2024
8f705ce
dao-table-class effective slot definitions now working, similar appro…
daninus14 Nov 2, 2024
f19dcab
setting inflate and deflate in mito.dao.table slot definitions
daninus14 Nov 2, 2024
1e8e52b
- setting the table-column-references found in the direct slot class …
daninus14 Nov 2, 2024
bd18cd2
adding log4cl and log4sly dependencies to qlot for local development
daninus14 Nov 2, 2024
5490f3a
ignoring emacs specific files
daninus14 Nov 2, 2024
92e2ffe
Merge branch 'effective-slots' into dn-develop
daninus14 Nov 2, 2024
4811ad0
Fixing test missing a col-type
daninus14 Nov 2, 2024
f2db481
Fixing test missing a col-type
daninus14 Nov 2, 2024
f77b79b
Fixing test missing a col-type
daninus14 Nov 2, 2024
22117c2
cleaning up comments
daninus14 Nov 2, 2024
14ef867
Merge branch 'effective-slots' into dn-develop
daninus14 Nov 2, 2024
be4fd2d
removing unnecessary setf
daninus14 Nov 7, 2024
344d432
cleaning up empty setf
daninus14 Nov 7, 2024
91ff46b
.gitignore emacs
daninus14 Nov 11, 2024
a0b298a
Check for slot bound before accessing. This was causing errors for :g…
daninus14 Nov 11, 2024
d1e5b72
Merge branch 'effective-slots' into dn-develop
daninus14 Nov 11, 2024
6187dc5
package reference from previous commit fixed, now other projects that…
daninus14 Nov 11, 2024
f548641
col-type was not being bound in effective slots in some cases, now pr…
daninus14 Nov 17, 2024
3a52363
Merge branch 'fukamachi:master' into master
daninus14 Nov 17, 2024
2bffc7b
Merge branch 'master' into effective-slots
daninus14 Nov 17, 2024
7de9d32
adding table-column-class convenience function for effective slots
daninus14 Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@

t/test.db
.qlot/
.emacs*
2 changes: 2 additions & 0 deletions qlfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ ql cl-mysql :upstream
ql dissect :upstream
ql sxql :upstream
ql rove :upstream
github sharplispers/log4cl
github 40ants/log4sly
8 changes: 8 additions & 0 deletions qlfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@
:initargs nil
:version "ql-upstream-cacea7331c10fe9d8398d104b2dfd579bf7ea353"
:remote-url "https://github.com/fukamachi/rove.git"))
("log4cl" .
(:class qlot/source/github:source-github
:initargs (:repos "sharplispers/log4cl" :ref nil :branch nil :tag nil)
:version "github-fe3da517147d023029782ced7cd989ba24f1e62d"))
("log4sly" .
(:class qlot/source/github:source-github
:initargs (:repos "40ants/log4sly" :ref nil :branch nil :tag nil)
:version "github-b229658c7fa8a8ff62cddd832e812cda96b50df6"))
39 changes: 28 additions & 11 deletions src/core/class/column.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
#:delete-from-plist
#:ensure-car)
(:export #:table-column-class
#:col-type
#:column-standard-effective-slot-definitions
#:table-column-type
#:%table-column-type
#:table-column-not-null-p
#:table-column-name
#:primary-key-p
Expand All @@ -29,14 +32,24 @@
(otherwise
(values col-type t))))

(defclass table-column-class (c2mop:standard-direct-slot-definition)

(defgeneric %table-column-type (obj))
(defmethod %table-column-type (ob) nil)
(defgeneric table-column-references (obj))
(defmethod table-column-references (ob) nil)
(defgeneric primary-key-p (obj))
(defmethod primary-key-p (ob) nil)
(defgeneric ghost-slot-p (obj))
(defmethod ghost-slot-p (ob) nil)

(defclass column-slot-definitions ()
((col-type :type (or symbol cons null)
:initarg :col-type
:accessor %table-column-type)
(references :type references
:initarg :references
:initform nil
:reader table-column-references)
:accessor table-column-references)
(primary-key :type boolean
:initarg :primary-key
:initform nil
Expand All @@ -47,17 +60,28 @@
:accessor ghost-slot-p
:documentation "Option to specify slots as ghost slots. Ghost slots do not depend on a database.")))

(defclass table-column-class (column-slot-definitions c2mop:standard-direct-slot-definition)
())

(defclass column-standard-effective-slot-definitions (column-slot-definitions
c2mop:standard-effective-slot-definition)
())

(defgeneric table-column-type (column)
(:method ((column table-column-class))
(values
(parse-col-type (%table-column-type column)))))
(parse-col-type (if (slot-boundp column 'col-type)
(%table-column-type column)
NIL)))))

(defgeneric table-column-not-null-p (column)
(:method ((column table-column-class))
(nth-value 1 (parse-col-type (%table-column-type column)))))

(defgeneric table-column-name (column)
(:method ((column table-column-class))
(unlispify (symbol-name-literally (c2mop:slot-definition-name column))))
(:method ((column column-standard-effective-slot-definitions))
(unlispify (symbol-name-literally (c2mop:slot-definition-name column)))))

(defmethod initialize-instance :around ((class table-column-class) &rest rest-initargs
Expand All @@ -69,14 +93,7 @@
(push (intern (symbol-name name) :keyword)
(getf rest-initargs :initargs)))

(let ((class (apply #'call-next-method class rest-initargs)))
(unless (slot-boundp class 'col-type)
(if (or (ghost-slot-p class)
(slot-value class 'references))
(setf (slot-value class 'col-type) nil)
(error 'col-type-required
:slot class)))
class))
(apply #'call-next-method class rest-initargs))

(defgeneric table-column-references-column (column))

Expand Down
31 changes: 31 additions & 0 deletions src/core/class/table.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
(:import-from #:mito.class.column
#:parse-col-type
#:table-column-class
#:table-column-references
#:column-standard-effective-slot-definitions
#:table-column-type
#:%table-column-type
#:table-column-name
#:primary-key-p
#:ghost-slot-p)
Expand Down Expand Up @@ -140,9 +143,37 @@
(defmethod c2mop:direct-slot-definition-class ((class table-class) &key &allow-other-keys)
'table-column-class)

(defmethod c2mop:effective-slot-definition-class ((class table-class) &rest initargs)
(declare (ignorable initargs))
(find-class 'column-standard-effective-slot-definitions))

(defmethod c2mop:validate-superclass ((class table-class) (super standard-class))
t)

(defmethod c2mop:compute-effective-slot-definition
:around ((class table-class) name direct-slot-definitions)
(declare (ignorable name))
(let* ((result (call-next-method))
(have-col-type-slot (remove-if-not
(lambda (x) (slot-exists-p x 'mito.class.column:col-type))
direct-slot-definitions))
(found-col-types (remove-if-not
(lambda (x) (slot-boundp x 'mito.class.column:col-type))
have-col-type-slot)))
;;(break)
(when result
;; set here all the relevant slots. See column-standard-effective-slot-definitions
(setf (ghost-slot-p result)
(some #'ghost-slot-p direct-slot-definitions))
(when found-col-types
(setf (%table-column-type result)
(some #'%table-column-type found-col-types)))
(setf (table-column-references result)
(some #'table-column-references direct-slot-definitions))
(setf (primary-key-p result)
(some #'primary-key-p direct-slot-definitions))
result)))

(defgeneric table-name (class)
(:method ((class table-class))
(if (slot-value class 'table-name)
Expand Down
37 changes: 34 additions & 3 deletions src/core/dao/column.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,63 @@
(:use #:cl
#:mito.util)
(:import-from #:mito.class.column
#:column-standard-effective-slot-definitions
#:table-column-class
#:table-column-type)
(:import-from #:local-time)
(:import-from #:cl-ppcre)
(:export #:dao-table-column-class
#:dao-table-column-inflate
#:dao-table-column-standard-effective-slot-definitions
#:dao-table-column-deflate
#:inflate
#:inflate-if-bound
#:deflate
#:deflate-if-bound
#:inflate-for-col-type
#:deflate-for-col-type))
(in-package :mito.dao.column)

(defparameter *conc-name* nil)

(defclass dao-table-column-class (table-column-class)
(defclass dao-table-column-slot-definitions ()
((inflate :type (or function null)
:accessor inflate
:initarg :inflate)
(deflate :type (or function null)
:accessor deflate
:initarg :deflate)))

(defgeneric inflate (obj))
(defmethod inflate (ob) nil)
(defgeneric inflate-if-bound (ob))
(defmethod inflate-if-bound (obj) nil)
(defmethod inflate-if-bound ((obj dao-table-column-slot-definitions))
(when (slot-boundp obj 'mito.dao.column:inflate)
(slot-value obj 'mito.dao.column:inflate)))
(defgeneric deflate (obj))
(defmethod deflate (ob) nil)
(defgeneric deflate-if-bound (ob))
(defmethod deflate-if-bound (obj) nil)
(defmethod deflate-if-bound ((obj dao-table-column-slot-definitions))
(when (slot-boundp obj 'mito.dao.column:deflate)
(slot-value obj 'mito.dao.column:deflate)))

(defclass dao-table-column-class (dao-table-column-slot-definitions table-column-class)
())

(defclass dao-table-column-standard-effective-slot-definitions
(dao-table-column-slot-definitions
column-standard-effective-slot-definitions)
())

(defmethod initialize-instance :around ((object dao-table-column-class) &rest rest-initargs
&key name readers writers inflate deflate
&allow-other-keys)
(when *conc-name*
(let ((accessor (intern
(format nil "~:@(~A~A~)" *conc-name* name)
*package*)))
(format nil "~:@(~A~A~)" *conc-name* name)
*package*)))
(unless readers
(pushnew accessor readers)
(setf (getf rest-initargs :readers) readers))
Expand Down
5 changes: 5 additions & 0 deletions src/core/dao/mixin.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#:table-column-name
#:table-column-references-column)
(:import-from #:mito.dao.column
#:dao-table-column-standard-effective-slot-definitions
#:dao-table-column-class
#:dao-table-column-inflate
#:*conc-name*)
Expand Down Expand Up @@ -46,6 +47,10 @@
(defmethod c2mop:direct-slot-definition-class ((class dao-table-mixin) &key)
'dao-table-column-class)

(defmethod c2mop:effective-slot-definition-class ((class dao-table-mixin) &rest initargs)
(declare (ignorable initargs))
(find-class 'mito.dao.column:dao-table-column-standard-effective-slot-definitions))

(defgeneric make-dao-instance (class &rest initargs)
(:method ((class-name symbol) &rest initargs)
(apply #'make-dao-instance
Expand Down
25 changes: 25 additions & 0 deletions src/core/dao/table.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
#:table-primary-key
#:create-table-sxql)
(:import-from #:mito.dao.column
#:inflate
#:inflate-if-bound
#:deflate-if-bound
#:deflate
#:dao-table-column-class
#:dao-table-column-standard-effective-slot-definitions
#:dao-table-column-inflate)
(:import-from #:mito.dao.mixin
#:dao-table-mixin
Expand All @@ -36,6 +41,26 @@
(defmethod c2mop:direct-slot-definition-class ((class dao-table-class) &key)
'dao-table-column-class)

(defmethod c2mop:effective-slot-definition-class ((class dao-table-class) &rest initargs)
(declare (ignorable initargs))
(find-class 'dao-table-column-standard-effective-slot-definitions))

(defmethod c2mop:validate-superclass ((class dao-table-class) (super standard-class))
t)

(defmethod c2mop:compute-effective-slot-definition
:around ((class dao-table-class) name direct-slot-definitions)
(declare (ignorable name))
(let ((result (call-next-method)))
(when result
;; set here all the relevant slots.
;; set here inflate and deflate from dao-table-column-standard-effective-slot-definitions
(setf (inflate result)
(some #'inflate-if-bound direct-slot-definitions))
(setf (deflate result)
(some #'deflate-if-bound direct-slot-definitions))
result)))

(defun initargs-enables-auto-pk (initargs)
(first (or (getf initargs :auto-pk) '(:serial))))

Expand Down
5 changes: 5 additions & 0 deletions src/core/dao/view.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#:table-class
#:table-name)
(:import-from #:mito.dao.column
#:dao-table-column-standard-effective-slot-definitions
#:dao-table-column-class)
(:import-from #:sxql)
(:export #:dao-table-view
Expand All @@ -20,6 +21,10 @@
(defmethod c2mop:direct-slot-definition-class ((class dao-table-view) &key)
'dao-table-column-class)

(defmethod c2mop:effective-slot-definition-class ((class dao-table-view) &rest initargs)
(declare (ignorable initargs))
(find-class 'mito.dao.column:dao-table-column-standard-effective-slot-definitions))

(defstruct (create-view (:include sxql.sql-type:sql-statement (sxql.sql-type:name "CREATE VIEW"))
(:constructor make-create-view (view-name &key or-replace as)))
view-name
Expand Down
2 changes: 1 addition & 1 deletion t/class.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@
)")
(is-table-class :mysql
(defclass tweet ()
((user-name :references (user name)))
((user-name :references (user name) :col-type (:or :null :text)))
(:metaclass table-class))
"CREATE TABLE tweet (
user_name VARCHAR(64) NOT NULL
Expand Down