Friedrich Dominicus wrote:
I got it (probably ;-), would someone mind to comment on it?
(in-package :qss.web)
;; (use-package :cells) (eval-when (:compile-toplevel :execute) (defparameter *example-app* (make-instance 'cookie-session-application :url-prefix "/ucw/examples/" :tal-generator (make-instance 'yaclml:file-system-generator :cachep t :root-directories (list *ucw-tal-root*)) :www-roots (list *ucw-tal-root*))))
;; (register-application *default-server* *example-app*)
(cells:defmodel controller (cells:model) ((view-obj :accessor view-obj :cell t :initarg :view-obj :initform (cells:c-in nil))
Later on in the render-on method you instantiate a controller thus:
(make-instance 'controller :view-obj (cells:c-in (init-view view)))
But I do not see any place in the code where you SETF the view-obj slot, so you could just:
(make-instance 'controller :view-obj (init-view view))
C-IN (or C-INPUT) is used only where, in brief, the application will be using SETF to change the value in a sempahoric slot. This is partly because a dataflow model needs to get the original dataflow from somewhere, usually from operating system events or a socket. One can also sometimes get simpler and more efficient code by skipping the declarative aspect (in which a slot like view-obj would have a rule) and just make the slot C-In and then setf that slot from output methods on on other slots. But like I said, that loses the advantages of a declarative approach.
Now in this case I further do not see view-obj getting involved in any cell-mediated dataflow, so I do not think it even needs to be a cell.
(db-obj :accessor db-obj :initarg :db-obj :cell t :initform (cells:c? (update-from-view cells:self)))))
The opening bit of update-from-view says:
(unless (slot-value self 'db-obj) .....)
Actually, the c? macro offers any existing value as a read macro:
(db-obj :accessor db-obj :initarg :db-obj :cell t :initform (cells:c? (unless .cache. (update-from-view cells:self))))
...and then do not check for an existing slot-value in u-f-v. Now I do have rare occasion to write code like that, but the interesting thing here is that this rule only runs once, after which it would always return the same value. So there is no dataflow here, where one thing changes (by a SETF of some c-input) and then a bunch of other things get updated automatically in a cascade of rule evaluations.
Maybe I missed something. My first question, does this code work for you? If so, what are the things you see happening that tell you it work? Just give me a simple scenario, such as "I start by reading in this stuff. Then I change this description field, then I exit, and when I look at the DB I see the new description text." Provide the sample code and explain where necessary which code does which step.
A big problem here is that I do not know SQL or cl-sql. For example, is a view just in-memory, or does it refer to a screen view? I know a relational view is just an abstraction built atop physical tables, so maybe you are just talking about that. Well, I do see:
(defcomponent example-view (simple-window-component) ((db-obj :initarg :db-obj :reader db-obj) (tag :accessor tag :initarg :tag :component (text-field :size 20 :maxlength 20)) (description :type string :accessor description :initarg :description :component (text-area-field :width 20 :height 10)) (other :accessor other :component (text-field :size 20 :maxlength 20))))
...and that looks like a GUI view component. Maybe the term is used both ways? if you are updating a description field in a GUI view and then seeing it written back out to the DB, maybe you could lay out for me the code path by which that happens.
I this a decent use of 'cells and is it cells-ish?
Pending a better understanding of the above questions, as I said, I do not see Cells doing very much, and so I would be surprised if they help in this case. But let's see what your feedback is on the above.
kt