introduced slot-def kind predicates (eg: join-slot-p key-slot-p)
[clsql.git] / sql / kmr-mop.lisp
1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          kmr-mop.lisp
6 ;;;; Purpose:       MOP support for multiple-implementions
7 ;;;; Programmer:    Kevin M. Rosenberg
8 ;;;; Date Started:  Apr 2003
9 ;;;;
10 ;;;; This file imports MOP symbols into the CLSQL-MOP package and then
11 ;;;; re-exports into CLSQL-SYS them to hide differences in
12 ;;;; MOP implementations.
13 ;;;;
14 ;;;; This file was extracted from the KMRCL utilities
15 ;;;; *************************************************************************
16
17 (in-package #:clsql-sys)
18
19 #+lispworks
20 (defun intern-eql-specializer (slot)
21   `(eql ,slot))
22
23 (defmacro process-class-option (metaclass slot-name &optional required)
24   #+lispworks
25   `(defmethod clos:process-a-class-option ((class ,metaclass)
26                                            (name (eql ,slot-name))
27                                            value)
28     (when (and ,required (null value))
29       (error "metaclass ~A class slot ~A must have a value" (quote ,metaclass) name))
30     (list name `',value))
31   #-lispworks
32     (declare (ignore metaclass slot-name required))
33     )
34
35 (defmacro process-slot-option (metaclass slot-name)
36   #+lispworks
37   `(defmethod clos:process-a-slot-option ((class ,metaclass)
38                                           (option (eql ,slot-name))
39                                           value
40                                           already-processed-options
41                                           slot)
42     (list* option `',value already-processed-options))
43   #-lispworks
44   (declare (ignore metaclass slot-name))
45   )
46
47 (eval-when (:compile-toplevel :load-toplevel :execute)
48   (defclass %slot-order-test-class ()
49     ((a)
50      (b)))
51   (finalize-inheritance (find-class '%slot-order-test-class))
52   (let ((slots (class-slots (find-class '%slot-order-test-class))))
53     (ecase (slot-definition-name (first slots))
54       (a)
55       (b (pushnew :mop-slot-order-reversed cl:*features*)))))
56
57 (defun ordered-class-slots (class)
58   #+mop-slot-order-reversed (reverse (class-slots class))
59   #-mop-slot-order-reversed (class-slots class))
60
61 (defun ordered-class-direct-slots (class)
62   "Gets an ordered list of direct class slots"
63   ;; NB: this used to return effective-slot-definitions in direct
64   ;; opposition to the function name.  Not sure why
65   (setf class (to-class class))
66   #+mop-slot-order-reversed (reverse (class-direct-slots class))
67   #-mop-slot-order-reversed (class-direct-slots class))
68
69 (defun find-slot-by-name (class slot-name &optional direct? recurse?)
70   "Looks up a direct-slot-definition by name"
71   (setf class (to-class class)
72         slot-name (to-slot-name slot-name))
73   (labels ((find-it (class)
74              (let* ((slots (if direct?
75                                (ordered-class-direct-slots class)
76                                (ordered-class-slots class)))
77                     (it (find slot-name
78                               slots
79                               :key #'slot-definition-name)))
80                (if it
81                    it
82                    (when recurse?
83                      (loop for sup in (class-direct-superclasses class)
84                            for rtn = (find-it sup)
85                            until rtn
86                            finally (return rtn)))))))
87     (find-it class)))
88
89 ;; Lispworks has symbol for slot rather than the slot instance
90 (defun %svuc-slot-name (slot)
91   #+lispworks slot
92   #-lispworks (slot-definition-name slot))
93
94 (defun %svuc-slot-object (slot class)
95   (declare (ignorable class))
96   #+lispworks (clos:find-slot-definition slot class)
97   #-lispworks slot)
98