added record of modifications to mewa object
[clinton/lisp-on-lines.git] / lisp-on-lines.lyx
1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
2 \lyxformat 221
3 \textclass article
4 \language english
5 \inputencoding auto
6 \fontscheme default
7 \graphics default
8 \paperfontsize default
9 \spacing single
10 \papersize a4paper
11 \paperpackage widemarginsa4
12 \use_geometry 0
13 \use_amsmath 0
14 \use_natbib 0
15 \use_numerical_citations 0
16 \paperorientation portrait
17 \secnumdepth 3
18 \tocdepth 3
19 \paragraph_separation indent
20 \defskip medskip
21 \quotes_language english
22 \quotes_times 2
23 \papercolumns 1
24 \papersides 1
25 \paperpagestyle default
26
27 \layout Title
28
29 LISP-ON-LINES
30 \layout Author
31
32
33 \noun on
34 Drew Crapmsie
35 \noun default
36 ,
37 \noun on
38 José Pablo Ezequiel
39 \begin_inset Quotes eld
40 \end_inset
41
42 Pupeno
43 \begin_inset Quotes erd
44 \end_inset
45
46 Fernández Silva
47 \layout Abstract
48
49
50 \noun on
51 Lisp-On-Lines
52 \noun default
53 is a very useful module that works on top of the
54 \noun on
55 UnCommon Web
56 \noun default
57 framework to do rapid developing of complex data-driven web appilcations
58 (on
59 \noun on
60 Common Lisp
61 \noun default
62 , of course).
63 \layout Section
64
65 Introduction
66 \layout Standard
67
68
69 \noun on
70 Lisp-On-Lines
71 \noun default
72 was founded and developed and continues to be developed and mantained by
73
74 \noun on
75 Drew Crapmsie
76 \noun default
77 .
78 \layout Subsection
79
80 Conventions
81 \layout Standard
82
83 The conventions used in this manual are:
84 \layout Itemize
85
86 Dode is shown as a monospace font.
87 When it is expected that the user is working in an interactive environment
88 what the user should type appears as bold, while the computer result appears
89 non-bold, for example:
90 \begin_deeper
91 \layout LyX-Code
92
93 >
94 \series bold
95 (+ 5 10)
96 \layout LyX-Code
97
98 15
99 \end_deeper
100 \layout Itemize
101
102 Names of people or products are show as small caps, like
103 \noun on
104 Drew Crapmsie
105 \noun default
106 or
107 \noun on
108 Lisp-On-Lines
109 \noun default
110 .
111 \layout Itemize
112
113 Sections marked with
114 \color red
115 ToDo
116 \color default
117 require further revision.
118 \layout Standard
119
120
121 \color red
122 ToDo: Add more conventions as they are needed, possible classes of text:
123 names of concepts, name of programming entities, like variables, functions,
124 etc (which are embedded in text, should they be shown monospaced ?).
125 \layout Section
126
127 Components
128 \layout Description
129
130 Meta\SpecialChar ~
131 Model\SpecialChar ~
132 Protocol A Protocol for introspection on relational objects.
133 \layout Description
134
135 Mewa\SpecialChar ~
136 Presentations A Mewa-like
137 \begin_inset Foot
138 collapsed true
139
140 \layout Standard
141
142 http://www.adrian-lienhard.ch/files/mewa.pdf
143 \end_inset
144
145 layer for UncommonWeb
146 \begin_inset Foot
147 collapsed true
148
149 \layout Standard
150
151 http://common-lisp.net/project/ucw/
152 \end_inset
153
154 Presentations.
155 \layout Section
156
157 Example
158 \layout Standard
159
160 First we start with the data model.
161 The Meta Model Protocol (MMP) is used to provide information on the data
162 objects and how they relate to one another.
163 Its is currently implemented as a layer over CLSQL
164 \begin_inset Foot
165 collapsed true
166
167 \layout Standard
168
169 http://clsql.b9.com/
170 \end_inset
171
172 , although support is planned for other backends (
173 \noun on
174 CLOS
175 \noun default
176 ,
177 \noun on
178 Elephant
179 \noun default
180 [4], whatever).
181 \layout Standard
182
183 The MMP shares its definition syntax with
184 \emph on
185 \noun on
186 CLSQL
187 \emph default
188 \noun default
189 's Object Oriented Data Definition Language (OODDL)
190 \begin_inset Foot
191 collapsed true
192
193 \layout Standard
194
195 http://clsql.b9.com/manual/ref-ooddl.html
196 \begin_inset Note
197 collapsed true
198
199 \layout Standard
200
201 Shouldn't this footnote be a bibliographical entry ? or something like that
202 ?
203 \end_inset
204
205
206 \end_inset
207
208 .
209 The macro to define view-classes is named DEF-VIEW-CLASS/META, and takes
210 the same arguments as DEF-VIEW-CLASS from CLSQL.
211 For the purposes of this simple example, we will only need two functions
212 from the MMP beyond what CLSQL provides : LIST-SLOTS and LIST-SLOT-TYPES[5].
213 \layout Standard
214
215 We'll define a simple class to hold a user.
216 \layout LyX-Code
217
218 >
219 \series bold
220 (def-view-class/meta user ()
221 \layout LyX-Code
222
223
224 \series bold
225 ((userid :initarg :userid :accessor userid :type integer :db-kind :key)
226 \layout LyX-Code
227
228
229 \series bold
230 (username :initarg :username :accessor username :type string :db-kind
231 :base)
232 \layout LyX-Code
233
234
235 \series bold
236 (password :initarg :password :accessor password :type string :db-kind
237 :base)))
238 \layout Standard
239
240 and now we create a user:
241 \layout LyX-Code
242
243 >
244 \series bold
245 (defparameter user (make-instance 'user :userid 1
246 \layout LyX-Code
247
248
249 \series bold
250 :username "drewc"
251 \layout LyX-Code
252
253
254 \series bold
255 :password "p@ssw0rd"))
256 \layout Standard
257
258 We can see the slots of users running:
259 \layout LyX-Code
260
261 >
262 \series bold
263 (lisp-on-lines::list-slots user)
264 \layout LyX-Code
265
266 (USERID USERNAME PASSWORD)
267 \layout Standard
268
269 or the types with:
270 \layout LyX-Code
271
272 >
273 \series bold
274 (lisp-on-lines::list-slot-types user)
275 \layout LyX-Code
276
277 ((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING))
278 \layout Standard
279
280 To see the default attributes of a class
281 \begin_inset Marginal
282 collapsed true
283
284 \layout Standard
285
286 Is this correct ? Drew, please, check.
287 \end_inset
288
289 we run.
290 \layout LyX-Code
291
292 >
293 \series bold
294 (lisp-on-lines::default-attributes user)
295 \layout LyX-Code
296
297 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
298 \layout LyX-Code
299
300 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
301 \layout LyX-Code
302
303 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
304 \layout Standard
305
306 To set the attributes of a class to the default values we use:
307 \layout LyX-Code
308
309 >
310 \series bold
311 (lisp-on-lines::set-default-attributes user)
312 \layout LyX-Code
313
314 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
315 \layout LyX-Code
316
317 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
318 \layout LyX-Code
319
320 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
321 \layout Standard
322
323 which takes an object of the class we are working with.
324 This is going to be change so we can do this action directly on the class.
325 It is on the TODO file.
326 \layout Standard
327
328 Class attributes?
329 \layout LyX-Code
330
331 >
332 \series bold
333 (lisp-on-lines::find-class-attributes user)
334 \layout LyX-Code
335
336 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
337 \layout LyX-Code
338
339 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
340 \layout LyX-Code
341
342 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
343 \layout LyX-Code
344
345 NIL)
346 \layout Standard
347
348 note that the mewa functions (find-attribute, set-attribute etc) can take
349 either an instance, or a class-name as a symbol:
350 \layout LyX-Code
351
352 >
353 \series bold
354 (lisp-on-lines::find-class-attributes 'user)
355 \layout LyX-Code
356
357 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
358 \layout LyX-Code
359
360 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
361 \layout LyX-Code
362
363 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
364 \layout LyX-Code
365
366 NIL)
367 \layout LyX-Code
368
369 >
370 \series bold
371 (lisp-on-lines::find-class-attributes (make-instance 'user))
372 \layout LyX-Code
373
374 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
375 \layout LyX-Code
376
377 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
378 \layout LyX-Code
379
380 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
381 \layout LyX-Code
382
383 NIL)
384 \layout Standard
385
386 Using that information, we have enough to create an interface to the object.
387
388 \noun on
389 UnCommon Web
390 \noun default
391 includes a powerful presentation system
392 \begin_inset Foot
393 collapsed true
394
395 \layout Standard
396
397 To see this system in action, we strongly recomend to study the presentations
398 example which comes with
399 \noun on
400 UnCommon Web
401 \noun default
402 .
403 Reading components/presentations.lisp can help understand a lot about how
404 presentations are built.
405 \end_inset
406
407 , but it is not dynamic enough for some of the most advanced applications.
408 Mewa defines an approach to presentations that solves that problem, but
409 the paper is written from a
410 \noun on
411 Smalltalk
412 \noun default
413 point of view.
414 A mixture of the two , Mewa Presentations(MP), is described here.
415 \layout Standard
416
417 MP introduces to
418 \noun on
419 UnCommon Web
420 \noun default
421 the concept of
422 \emph on
423 attributes
424 \emph default
425 .
426 An attribute is essentially a named version of the DEFPRESENTATION slot-like
427 arguments, for example in :
428 \layout LyX-Code
429
430 >
431 \series bold
432 (defpresentation person-editor (object-presentation)
433 \layout LyX-Code
434
435
436 \series bold
437 ((string :label "First Name" :slot-name 'first-name :max-length 30)))
438 \layout Standard
439
440 the (string :label "First Name" ...) form is an attribute definiton.
441 Attributes are accessed through FIND-ATTIRIBUTES, and are composed at run
442 time (where the
443 \noun on
444 UnCommon Web
445 \noun default
446 's presentation system is done at compile time) to display the object.
447 This allows a very flexible system of displaying objects which is reminiscent
448 of
449 \noun on
450 CSS
451 \noun default
452
453 \begin_inset Foot
454 collapsed true
455
456 \layout Standard
457
458
459 \noun on
460 Drew Crapmsie
461 \noun default
462 discovered this, rather than invent or design it, so there are some rough
463 edges, but its a good start.
464 \end_inset
465
466 .
467 \layout Standard
468
469 Its much easier to show this than to tell.
470 Lets present our user class.
471 Currently in
472 \noun on
473 UnCommon Web
474 \noun default
475 , you'd define a presentation as such :
476 \layout LyX-Code
477
478 >
479 \series bold
480 (defpresentation user-presentation (object-presentation)
481 \layout LyX-Code
482
483 ((INTEGER :LABEL "USERID" :SLOT-NAME USERID)
484 \layout LyX-Code
485
486 (STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
487 \layout LyX-Code
488
489 (STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)))
490 \layout Standard
491
492 which could be presented using PRESENT-OBJECT :
493 \layout LyX-Code
494
495 >
496 \series bold
497 (present-object user :using 'user-presentation)
498 \layout Standard
499
500 The equivalent approach using mewa presentations is actually longer and
501 more verbose(!) but it serves to demonstrate how the MP system works.
502 \layout Standard
503
504 Mewa Presentations adds a set of attributes to a class, keyed off the class
505 name.
506 Attributes are inherited, so if you define an attribute on T, you can use
507 it with any class.
508 \layout Standard
509
510 MP stores named attributes keyed on a class name.
511 To achieve the same functionality as the above using mp would look like
512 this :
513 \layout LyX-Code
514
515 >
516 \series bold
517 (setf (lisp-on-lines::find-attribute 'user :viewer)
518 \begin_inset Marginal
519 collapsed true
520
521 \layout Standard
522
523 Isn't this too imperative (in contrast to functional, lispy).
524 \end_inset
525
526
527 \layout LyX-Code
528
529
530 \series bold
531 '(lisp-on-lines::mewa-object-presentation
532 \layout LyX-Code
533
534
535 \series bold
536 :attributes (userid username password)
537 \layout LyX-Code
538
539
540 \series bold
541 :global-properties (:editablep nil)))
542 \layout LyX-Code
543
544 (:VIEWER MEWA-OBJECT-PRESENTATION
545 \layout LyX-Code
546
547 :ATTRIBUTES
548 \layout LyX-Code
549
550 (USERID USERNAME PASSWORD)
551 \layout LyX-Code
552
553 :GLOBAL-PROPERTIES
554 \layout LyX-Code
555
556 (:EDITABLEP NIL))
557 \layout LyX-Code
558
559 >
560 \series bold
561 (setf (lisp-on-lines::find-attribute 'user 'userid)
562 \begin_inset Marginal
563 collapsed true
564
565 \layout Standard
566
567 Are this setfs to 'userid, 'username and 'password needed ? I (Pupeno) inspected
568 they contents at of this moment and they seem to already contain what they
569 are being set to.
570 \end_inset
571
572
573 \layout LyX-Code
574
575
576 \series bold
577 '(integer :label "userid" :slot-name userid))
578 \layout LyX-Code
579
580 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
581 \layout LyX-Code
582
583 >
584 \series bold
585 (setf (lisp-on-lines::find-attribute 'user 'username)
586 \layout LyX-Code
587
588
589 \series bold
590 '(STRING :LABEL "USERNAME" :SLOT-NAME USERNAME))
591 \layout LyX-Code
592
593 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
594 \layout LyX-Code
595
596 >
597 \series bold
598 (setf (lisp-on-lines::find-attribute 'user 'password)
599 \layout LyX-Code
600
601
602 \series bold
603 '(STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD))
604 \layout LyX-Code
605
606 (PASSWORD STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD)
607 \layout LyX-Code
608
609 >
610 \series bold
611 (lisp-on-lines::find-class-attributes 'user)
612 \layout LyX-Code
613
614 (USER
615 \layout LyX-Code
616
617 (:VIEWER MEWA-OBJECT-PRESENTATION
618 \layout LyX-Code
619
620 :ATTRIBUTES
621 \layout LyX-Code
622
623 (USERID USERNAME PASSWORD)
624 \layout LyX-Code
625
626 :GLOBAL-PROPERTIES
627 \layout LyX-Code
628
629 (:EDITABLEP NIL))
630 \layout LyX-Code
631
632 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
633 \layout LyX-Code
634
635 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
636 \layout LyX-Code
637
638 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
639 \layout LyX-Code
640
641 NIL)
642 \layout Standard
643
644 this is all turned into a
645 \noun on
646 UnCommon Web
647 \noun default
648 presentation at runtime using MAKE-PRESENTATION, for example, the following
649 code should be enough to show what's built so far attached to the examples
650 application:
651 \layout LyX-Code
652
653 >
654 \series bold
655 (defcomponent lol-example (window-component)
656 \layout LyX-Code
657
658
659 \series bold
660 ())
661 \layout LyX-Code
662
663 >
664 \series bold
665 (defmethod render-on ((res response) (lol-example lol-example))
666 \layout LyX-Code
667
668
669 \series bold
670 (<:h1 "User")
671 \layout LyX-Code
672
673
674 \series bold
675 (<ucw:render-component :component (lisp-on-lines::make-presentation
676 user :type :viewer)))
677 \layout LyX-Code
678
679 >
680 \series bold
681 (defentry-point "lol.ucw" (:application *example-application*) ()
682 \layout LyX-Code
683
684
685 \series bold
686 (call 'products-presentation))
687 \layout Standard
688
689 As you'll see, nothing is exported from the LISP-ON-LINES package.
690 If you wish to use LOL in your own package (or in UCW-USER or whatever),
691 you simply need to use the MEWA and META-MODEL packages.
692 \layout Standard
693
694 SET-ATTRIBUTE can be used in place of (setf (find-attribute)) when you want
695 to "inherit" the properties of an existing attribute definition :
696 \layout Standard
697
698 LISP-ON-LINES> (set-attribute 'user 'password '(string :label "password:
699 (must be at leat 8 chars)"))
700 \layout Standard
701
702 (PASSWORD STRING
703 \layout Standard
704
705 :LABEL
706 \layout Standard
707
708 "password: (must be at leat 8 chars)"
709 \layout Standard
710
711 :SLOT-NAME
712 \layout Standard
713
714 PASSWORD)
715 \layout Standard
716
717 Now we want to create a presentation with which to edit the username.
718 we will use the existing attributes on a subclass of mewa-object-presetation
719 :
720 \layout Standard
721
722 LISP-ON-LINES> (defcomponent user-editor (mewa-object-presentation)
723 \layout Standard
724
725 ()
726 \layout Standard
727
728 (:default-initargs
729 \layout Standard
730
731 :attributes '((username :label "Enter your New Username") password)
732 \layout Standard
733
734 :global-properties '(:editablep t)))
735 \layout Standard
736
737 USER-EDITOR
738 \layout Standard
739
740 LISP-ON-LINES> (setf (find-attribute 'user :editor) '(user-editor))
741 \layout Standard
742
743 (:EDITOR USER-EDITOR)
744 \layout Standard
745
746 LISP-ON-LINES>
747 \layout Standard
748
749 which we then can display below our earlier example :
750 \layout Standard
751
752 (defmethod render-on ((res response) (e presentations-index))
753 \layout Standard
754
755 "
756 \layout Standard
757
758 As you'll see, nothing is exported from the LISP-ON-LINES package.
759
760 \layout Standard
761
762 if you wish to use LOL in your own package (or in UCW-USER or whatever),
763 \layout Standard
764
765 you simply need to use the MEWA and META-MODEL packages"
766 \layout Standard
767
768 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
769 s::user :type :viewer))
770 \layout Standard
771
772 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
773 s::user :type :editor)))
774 \layout Standard
775
776 that should give you some idea on how it works ..
777 ask me when you get confused :)
778 \layout Section
779
780 Pupeno's Example
781 \layout Standard
782
783 This is Pupeno's view of how to do rapid developing of a database-driven
784 web application.
785 It currently is going to assume a very specific case but latter it may
786 be made bigger.
787 \layout Standard
788
789 We first start with a
790 \noun on
791 PostgreSQL
792 \noun default
793 connection of CLSQL which is set up with one line:
794 \layout LyX-Code
795
796 >
797 \series bold
798 (clsql:connect '("localhost" "geo" "geo" "geogeo"))
799 \layout Standard
800
801 which connect us to the server on
802 \family typewriter
803 localhost
804 \family default
805 , to the database
806 \family typewriter
807 geo
808 \family default
809 as user
810 \begin_inset Quotes eld
811 \end_inset
812
813 geo
814 \begin_inset Quotes erd
815 \end_inset
816
817 with password
818 \begin_inset Quotes eld
819 \end_inset
820
821 geogeo
822 \begin_inset Quotes erd
823 \end_inset
824
825 (this is not a smart way to generate password, don't do this).
826 To have a nice SQL environment, we also want:
827 \layout LyX-Code
828
829 >
830 \series bold
831 (clsql:locally-enable-sql-reader-syntax)
832 \layout LyX-Code
833
834 >
835 \series bold
836 (setf clsql:*default-caching* nil)
837 \layout Standard
838
839 Actually, it is more than a nice environmnet, without those lines the rest
840 of the code won't work.
841 \layout Standard
842
843 On the
844 \family typewriter
845 geo
846 \family default
847 database, there's a table called
848 \family typewriter
849 product
850 \family default
851 which has the following structure:
852 \layout LyX-Code
853
854
855 \series bold
856 CREATE TABLE product (
857 \layout LyX-Code
858
859
860 \series bold
861 id serial NOT NULL,
862 \layout LyX-Code
863
864
865 \series bold
866 name text NOT NULL,
867 \layout LyX-Code
868
869
870 \series bold
871 details text,
872 \layout LyX-Code
873
874
875 \series bold
876 description text,
877 \layout LyX-Code
878
879
880 \series bold
881 cost double precision,
882 \layout LyX-Code
883
884
885 \series bold
886 CONSTRAINT product_cost_check CHECK ((cost > (0)::double precision))
887 \layout LyX-Code
888
889
890 \series bold
891 );
892 \layout LyX-Code
893
894
895 \series bold
896 ALTER TABLE ONLY product ADD CONSTRAINT product_name_key UNIQUE (name);
897 \layout LyX-Code
898
899
900 \series bold
901 ALTER TABLE ONLY product ADD CONSTRAINT product_pkey PRIMARY KEY (id);
902 \layout Standard
903
904
905 \color red
906 ToDo: express the table structure in a better way.
907 \layout Standard
908
909 Now we'll create the class that represents a product, mirroring the database
910 structure:
911 \layout LyX-Code
912
913 >
914 \series bold
915 (lisp-on-lines::def-view-class/table "product")
916 \layout Standard
917
918 and then we generate the default attributes (from
919 \family typewriter
920 product
921 \family default
922 's slots) and assign it to
923 \family typewriter
924 product
925 \family default
926 :
927 \layout LyX-Code
928
929 >
930 \series bold
931 (lisp-on-lines::set-default-attributes (make-instance 'product))
932 \begin_inset Marginal
933 collapsed true
934
935 \layout Standard
936
937 set-default-attributes is marked to be renamed to set-generated-attributes.
938 \end_inset
939
940
941 \layout Standard
942
943 As you can see, we instantiate
944 \family typewriter
945 product
946 \family default
947 to pass it to
948 \family typewriter
949 set-default-attributes
950 \family default
951 , because it expects an object instead of a class.
952 We don't need the object anymore, so we don't save any reference to it.
953 In the future we might have a
954 \family typewriter
955 set-default-attributes
956 \family default
957 that can use a class directly.
958 Now we set a the attribute
959 \family typewriter
960 :viewer
961 \family default
962 to contain the
963 \family typewriter
964 mewa-object-presentation
965 \family default
966 exposing the attributes we like the user to work with:
967 \layout LyX-Code
968
969 >
970 \series bold
971 (setf (lisp-on-lines::find-attribute (make-instance 'product) :viewer)
972 \layout LyX-Code
973
974
975 \series bold
976 '(lisp-on-lines::mewa-object-presentation
977 \layout LyX-Code
978
979
980 \series bold
981 :attributes (name details description cost)
982 \layout LyX-Code
983
984
985 \series bold
986 :global-properties (:editablep nil)))
987 \layout Standard
988
989 The last parameter shows that it is not editable, which makes sense for
990 a viewer.
991 \the_end