X-Git-Url: https://git.hcoop.net/clinton/lisp-on-lines.git/blobdiff_plain/792bdc71b3815c3890b5430c706362b22635cbff..6460c439effcc70efa79d74850500484b484a855:/lisp-on-lines.lyx diff --git a/lisp-on-lines.lyx b/lisp-on-lines.lyx index 4752559..dcbe7b4 100644 --- a/lisp-on-lines.lyx +++ b/lisp-on-lines.lyx @@ -6,8 +6,9 @@ \fontscheme default \graphics default \paperfontsize default -\papersize Default -\paperpackage a4 +\spacing single +\papersize a4paper +\paperpackage widemarginsa4 \use_geometry 0 \use_amsmath 0 \use_natbib 0 @@ -26,6 +27,101 @@ \layout Title LISP-ON-LINES +\layout Author + + +\noun on +Drew Crapmsie +\noun default +, +\noun on +José Pablo Ezequiel +\begin_inset Quotes eld +\end_inset + +Pupeno +\begin_inset Quotes erd +\end_inset + + Fernández Silva +\layout Abstract + + +\noun on +Lisp-On-Lines +\noun default + is a very useful module that works on top of the +\noun on +UnCommon Web +\noun default + framework to do rapid developing of complex data-driven web appilcations + (on +\noun on +Common Lisp +\noun default +, of course). +\layout Section + +Introduction +\layout Standard + + +\noun on +Lisp-On-Lines +\noun default + was founded and developed and continues to be developed and mantained by + +\noun on +Drew Crapmsie +\noun default +. +\layout Subsection + +Conventions +\layout Standard + +The conventions used in this manual are: +\layout Itemize + +Dode is shown as a monospace font. + When it is expected that the user is working in an interactive environment + what the user should type appears as bold, while the computer result appears + non-bold, for example: +\begin_deeper +\layout LyX-Code + +> +\series bold +(+ 5 10) +\layout LyX-Code + +15 +\end_deeper +\layout Itemize + +Names of people or products are show as small caps, like +\noun on +Drew Crapmsie +\noun default + or +\noun on +Lisp-On-Lines +\noun default +. +\layout Itemize + +Sections marked with +\color red +ToDo +\color default + require further revision. +\layout Standard + + +\color red +ToDo: Add more conventions as they are needed, possible classes of text: + names of concepts, name of programming entities, like variables, functions, + etc (which are embedded in text, should they be shown monospaced ?). \layout Section Components @@ -58,18 +154,7 @@ http://common-lisp.net/project/ucw/ Presentations. \layout Section -Description -\layout Standard - -LISP-ON-LINES (LOL) is a framework for rapid development of complex data-driven - web appilcations. - -\layout Section - -Introduction: -\layout Section - -Example: +Example \layout Standard First we start with the data model. @@ -84,11 +169,24 @@ collapsed true http://clsql.b9.com/ \end_inset -, although support is planned for other backends (CLOS, Elephant[4], whatever). -\layout Standard - -The MMP shares its definition syntax with CLSQL's Object Oriented Data Definitio -n Language (OODDL) +, although support is planned for other backends ( +\noun on +CLOS +\noun default +, +\noun on +Elephant +\noun default +[4], whatever). +\layout Standard + +The MMP shares its definition syntax with +\emph on +\noun on +CLSQL +\emph default +\noun default +'s Object Oriented Data Definition Language (OODDL) \begin_inset Foot collapsed true @@ -117,207 +215,290 @@ Shouldn't this footnote be a bibliographical entry ? or something like that We'll define a simple class to hold a user. \layout LyX-Code +> +\series bold (def-view-class/meta user () \layout LyX-Code - ((userid :initarg :userid :accessor userid :type integer :db-kind :key) -\layout LyX-Code - (username :initarg :username :accessor username :type string :db-kind - :base) +\series bold + ((userid :initarg :userid :accessor userid :type integer :db-kind :key) \layout LyX-Code - (password :initarg :password :accessor password :type string :db-kind - :base))) -\layout LyX-Code +\series bold + (username :initarg :username :accessor username :type string :db-kind + :base) \layout LyX-Code -STYLE-WARNING: redefining META-MODEL.METADATA (USER) in DEFMETHOD -\layout LyX-Code -# -\layout LyX-Code +\series bold + (password :initarg :password :accessor password :type string :db-kind + :base))) +\layout Standard +and now we create a user: \layout LyX-Code +> +\series bold (defparameter user (make-instance 'user :userid 1 \layout LyX-Code - :username "drewc" -\layout LyX-Code - :password "p@ssw0rd")) +\series bold + :username "drewc" \layout LyX-Code -\layout LyX-Code -USER -\layout LyX-Code +\series bold + :password "p@ssw0rd")) +\layout Standard +We can see the slots of users running: \layout LyX-Code -LISP-ON-LINES> (list-slots user) +> +\series bold +(lisp-on-lines::list-slots user) \layout LyX-Code (USERID USERNAME PASSWORD) -\layout LyX-Code +\layout Standard -LISP-ON-LINES> (list-slot-types user) +or the types with: \layout LyX-Code -((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING)) +> +\series bold +(lisp-on-lines::list-slot-types user) \layout LyX-Code -; compiling file "/tmp/fileQQsHyN" (written 03 JUN 2005 03:20:06 PM): -\layout LyX-Code +((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING)) +\layout Standard -; /tmp/fileQQsHyN.fasl written -\layout LyX-Code +To see the default attributes of a class +\begin_inset Marginal +collapsed true -; compilation finished in 0:00:00 -\layout LyX-Code +\layout Standard -\layout LyX-Code +Is this correct ? Drew, please, check. +\end_inset + we run. \layout LyX-Code -(default-attributes user) +> +\series bold +(lisp-on-lines::default-attributes user) \layout LyX-Code - ((userid integer :label "User ID" :slot-name 'userid) +((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) \layout LyX-Code - (username string :label "User name" :slot-name 'username) + (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) \layout LyX-Code - (password string :label "Password" :slot-name 'password)) -\layout LyX-Code + (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)) +\layout Standard +To set the attributes of a class to the default values we use: \layout LyX-Code -LISP-ON-LINES> (set-default-attributes user) +> +\series bold +(lisp-on-lines::set-default-attributes user) \layout LyX-Code ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) \layout LyX-Code -(USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) + (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) \layout LyX-Code -(PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)) -\layout LyX-Code + (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)) +\layout Standard -LISP-ON-LINES> (find-class-attributes user) -\layout LyX-Code +which takes an object of the class we are working with. + This is going to be change so we can do this action directly on the class. + It is on the TODO file. +\layout Standard -(USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) +Class attributes? \layout LyX-Code -(USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) +> +\series bold +(lisp-on-lines::find-class-attributes user) \layout LyX-Code -(USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) +(USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) \layout LyX-Code -COMMON-LISP:NIL) + (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) \layout LyX-Code -LISP-ON-LINES> ;;;; note that the mewa functions (find-attribute, set-attribute - etc) can take either an instance, or a class-name as a symbol , ie : + (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) \layout LyX-Code -; No value + NIL) +\layout Standard + +note that the mewa functions (find-attribute, set-attribute etc) can take + either an instance, or a class-name as a symbol: \layout LyX-Code -LISP-ON-LINES> (find-class-attributes 'user) +> +\series bold +(lisp-on-lines::find-class-attributes 'user) \layout LyX-Code (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) \layout LyX-Code -(USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) + (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) \layout LyX-Code -(USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) + (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) \layout LyX-Code -COMMON-LISP:NIL) + NIL) \layout LyX-Code -LISP-ON-LINES> (find-class-attributes (make-instance 'user)) +> +\series bold +(lisp-on-lines::find-class-attributes (make-instance 'user)) \layout LyX-Code (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) \layout LyX-Code -(USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) + (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) \layout LyX-Code -(USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) + (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) \layout LyX-Code -COMMON-LISP:NIL) -\layout LyX-Code - -LISP-ON-LINES> + NIL) \layout Standard Using that information, we have enough to create an interface to the object. - UncommonWeb includes a powerful presentation system, but it is not quite - dynamic enough for our needs. - Mewa defines an approach to presentations that suits our purposes, but - the paper is written from a smalltalk point of view. - A mixture of the two , Mewa Presentations(MP), is described here. + +\noun on +UnCommon Web +\noun default + includes a powerful presentation system +\begin_inset Foot +collapsed true + \layout Standard -MP introduces to UCW the concept of attributes. - an attribute is essentially a named version of the defpresentation slot-like - arguments. - for example in : +To see this system in action, we strongly recomend to study the presentations + example which comes with +\noun on +UnCommon Web +\noun default +. + Reading components/presentations.lisp can help understand a lot about how + presentations are built. +\end_inset + +, but it is not dynamic enough for some of the most advanced applications. + Mewa defines an approach to presentations that solves that problem, but + the paper is written from a +\noun on +Smalltalk +\noun default + point of view. + A mixture of the two , Mewa Presentations(MP), is described here. \layout Standard +MP introduces to +\noun on +UnCommon Web +\noun default + the concept of +\emph on +attributes +\emph default +. + An attribute is essentially a named version of the DEFPRESENTATION slot-like + arguments, for example in : +\layout LyX-Code + +> +\series bold (defpresentation person-editor (object-presentation) -\layout Standard +\layout LyX-Code + -((string :label "First Name" :slot-name 'first-name :max-length 30))) +\series bold + ((string :label "First Name" :slot-name 'first-name :max-length 30))) \layout Standard the (string :label "First Name" ...) form is an attribute definiton. Attributes are accessed through FIND-ATTIRIBUTES, and are composed at run - time (where the current system is done at compile time) to display the - object. + time (where the +\noun on +UnCommon Web +\noun default +'s presentation system is done at compile time) to display the object. This allows a very flexible system of displaying objects which is reminiscent - of CSS. - I discovered this, rather than invent or design it, so there are some rough + of +\noun on +CSS +\noun default + +\begin_inset Foot +collapsed true + +\layout Standard + + +\noun on +Drew Crapmsie +\noun default + discovered this, rather than invent or design it, so there are some rough edges, but its a good start. +\end_inset + +. \layout Standard -Its much easier to show this then to tell. +Its much easier to show this than to tell. Lets present our user class. - Currently in UCW, you'd define a presentation as such : -\layout Standard + Currently in +\noun on +UnCommon Web +\noun default +, you'd define a presentation as such : +\layout LyX-Code +> +\series bold (defpresentation user-presentation (object-presentation) -\layout Standard +\layout LyX-Code ((INTEGER :LABEL "USERID" :SLOT-NAME USERID) -\layout Standard +\layout LyX-Code -(STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) -\layout Standard + (STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) +\layout LyX-Code -(STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))) + (STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))) \layout Standard which could be presented using PRESENT-OBJECT : -\layout Standard +\layout LyX-Code +> +\series bold (present-object user :using 'user-presentation) \layout Standard -The equiv approach using mewa presentations is actually longer and more - verbose(!) but it serves to demonstrate how the MP system works. +The equivalent approach using mewa presentations is actually longer and + more verbose(!) but it serves to demonstrate how the MP system works. \layout Standard Mewa Presentations adds a set of attributes to a class, keyed off the class @@ -327,102 +508,187 @@ Mewa Presentations adds a set of attributes to a class, keyed off the class \layout Standard MP stores named attributes keyed on a class name. - to achieve the same functionality as the above using mp would look like + To achieve the same functionality as the above using mp would look like this : -\layout Standard +\layout LyX-Code + +> +\series bold +(setf (lisp-on-lines::find-attribute 'user :viewer) +\begin_inset Marginal +collapsed true -LISP-ON-LINES> (setf (find-attribute 'user :viewer) '(mewa-object-presentation - :attributes (userid username password) :global-properties (:editablep nil))) \layout Standard +Isn't this too imperative (in contrast to functional, lispy). +\end_inset + + +\layout LyX-Code + + +\series bold + '(lisp-on-lines::mewa-object-presentation +\layout LyX-Code + + +\series bold + :attributes (userid username password) +\layout LyX-Code + + +\series bold + :global-properties (:editablep nil))) +\layout LyX-Code + (:VIEWER MEWA-OBJECT-PRESENTATION -\layout Standard +\layout LyX-Code -:ATTRIBUTES -\layout Standard + :ATTRIBUTES +\layout LyX-Code -(USERID USERNAME PASSWORD) -\layout Standard + (USERID USERNAME PASSWORD) +\layout LyX-Code -:GLOBAL-PROPERTIES -\layout Standard + :GLOBAL-PROPERTIES +\layout LyX-Code -(:EDITABLEP NIL)) -\layout Standard + (:EDITABLEP NIL)) +\layout LyX-Code + +> +\series bold +(setf (lisp-on-lines::find-attribute 'user 'userid) +\begin_inset Marginal +collapsed true -LISP-ON-LINES> (setf (find-attribute 'user 'userid) '(INTEGER :LABEL "USERID" - :SLOT-NAME USERID)) \layout Standard +Are this setfs to 'userid, 'username and 'password needed ? I (Pupeno) inspected + they contents at of this moment and they seem to already contain what they + are being set to. +\end_inset + + +\layout LyX-Code + + +\series bold + '(integer :label "userid" :slot-name userid)) +\layout LyX-Code + (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) -\layout Standard +\layout LyX-Code -LISP-ON-LINES> (setf (find-attribute 'user 'username) '(STRING :LABEL "USERNAME" - :SLOT-NAME USERNAME)) -\layout Standard +> +\series bold +(setf (lisp-on-lines::find-attribute 'user 'username) +\layout LyX-Code + + +\series bold + '(STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)) +\layout LyX-Code (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) -\layout Standard +\layout LyX-Code -LISP-ON-LINES> (setf (find-attribute 'user 'password) '(STRING :LABEL "USERNAME" - :SLOT-NAME PASSWORD)) -\layout Standard +> +\series bold +(setf (lisp-on-lines::find-attribute 'user 'password) +\layout LyX-Code + + +\series bold + '(STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD)) +\layout LyX-Code (PASSWORD STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD) -\layout Standard +\layout LyX-Code -LISP-ON-LINES> (find-class-attributes 'user) -\layout Standard +> +\series bold +(lisp-on-lines::find-class-attributes 'user) +\layout LyX-Code -(USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) -\layout Standard +(USER +\layout LyX-Code -(USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) -\layout Standard + (:VIEWER MEWA-OBJECT-PRESENTATION +\layout LyX-Code -(USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) -\layout Standard + :ATTRIBUTES +\layout LyX-Code -(:VIEWER MEWA-OBJECT-PRESENTATION -\layout Standard + (USERID USERNAME PASSWORD) +\layout LyX-Code -:ATTRIBUTES -\layout Standard + :GLOBAL-PROPERTIES +\layout LyX-Code -(USERID USERNAME PASSWORD) -\layout Standard + (:EDITABLEP NIL)) +\layout LyX-Code -:GLOBAL-PROPERTIES -\layout Standard + (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) +\layout LyX-Code -(:EDITABLEP NIL)) -\layout Standard + (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) +\layout LyX-Code -COMMON-LISP:NIL) -\layout Standard + (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) +\layout LyX-Code -this is all turned into a UCW presentation at runtime using MAKE-PRESENTATION - : + NIL) \layout Standard -(defmethod render-on ((res response) (e presentations-index)) -\layout Standard +this is all turned into a +\noun on +UnCommon Web +\noun default + presentation at runtime using MAKE-PRESENTATION, for example, the following + code should be enough to show what's built so far attached to the examples + application: +\layout LyX-Code -" -\layout Standard +> +\series bold +(defcomponent lol-example (window-component) +\layout LyX-Code -As you'll see, nothing is exported from the LISP-ON-LINES package. - -\layout Standard -if you wish to use LOL in your own package (or in UCW-USER or whatever), -\layout Standard +\series bold + ()) +\layout LyX-Code -you simply need to use the MEWA and META-MODEL packages" +> +\series bold +(defmethod render-on ((res response) (lol-example lol-example)) +\layout LyX-Code + + +\series bold + (<:h1 "User") +\layout LyX-Code + + +\series bold + ( +\series bold +(defentry-point "lol.ucw" (:application *example-application*) () +\layout LyX-Code + + +\series bold + (call 'products-presentation)) \layout Standard -( +\series bold +(clsql:connect '("localhost" "geo" "geo" "geogeo")) +\layout Standard + +which connect us to the server on +\family typewriter +localhost +\family default +, to the database +\family typewriter +geo +\family default + as user +\begin_inset Quotes eld +\end_inset + +geo +\begin_inset Quotes erd +\end_inset + + with password +\begin_inset Quotes eld +\end_inset + +geogeo +\begin_inset Quotes erd +\end_inset + + (this is not a smart way to generate password, don't do this). + To have a nice SQL environment, we also want: +\layout LyX-Code + +> +\series bold +(clsql:locally-enable-sql-reader-syntax) +\layout LyX-Code + +> +\series bold +(setf clsql:*default-caching* nil) +\layout Standard + +Actually, it is more than a nice environmnet, without those lines the rest + of the code won't work. +\layout Standard + +On the +\family typewriter +geo +\family default + database, there's a table called +\family typewriter +product +\family default + which has the following structure: +\layout LyX-Code + + +\series bold +CREATE TABLE product ( +\layout LyX-Code + + +\series bold + id serial NOT NULL, +\layout LyX-Code + + +\series bold + name text NOT NULL, +\layout LyX-Code + + +\series bold + details text, +\layout LyX-Code + + +\series bold + description text, +\layout LyX-Code + + +\series bold + cost double precision, +\layout LyX-Code + + +\series bold + CONSTRAINT product_cost_check CHECK ((cost > (0)::double precision)) +\layout LyX-Code + + +\series bold +); +\layout LyX-Code + + +\series bold +ALTER TABLE ONLY product ADD CONSTRAINT product_name_key UNIQUE (name); +\layout LyX-Code + + +\series bold +ALTER TABLE ONLY product ADD CONSTRAINT product_pkey PRIMARY KEY (id); +\layout Standard + + +\color red +ToDo: express the table structure in a better way. +\layout Standard + +Now we'll create the class that represents a product, mirroring the database + structure: +\layout LyX-Code + +> +\series bold +(lisp-on-lines::def-view-class/table "product") +\layout Standard + +and then we generate the default attributes (from +\family typewriter +product +\family default +'s slots) and assign it to +\family typewriter +product +\family default +: +\layout LyX-Code + +> +\series bold +(lisp-on-lines::set-default-attributes (make-instance 'product)) +\begin_inset Marginal +collapsed true + +\layout Standard + +set-default-attributes is marked to be renamed to set-generated-attributes. +\end_inset + + +\layout Standard + +As you can see, we instantiate +\family typewriter +product +\family default + to pass it to +\family typewriter +set-default-attributes +\family default +, because it expects an object instead of a class. + We don't need the object anymore, so we don't save any reference to it. + In the future we might have a +\family typewriter +set-default-attributes +\family default + that can use a class directly. + Now we set a the attribute +\family typewriter +:viewer +\family default + to contain the +\family typewriter +mewa-object-presentation +\family default + exposing the attributes we like the user to work with: +\layout LyX-Code + +> +\series bold +(setf (lisp-on-lines::find-attribute (make-instance 'product) :viewer) +\layout LyX-Code + + +\series bold + '(lisp-on-lines::mewa-object-presentation +\layout LyX-Code + + +\series bold + :attributes (name details description cost) +\layout LyX-Code + + +\series bold + :global-properties (:editablep nil))) +\layout Standard + +The last parameter shows that it is not editable, which makes sense for + a viewer. \the_end