This is Chapter 4 which deals with Seekers, Action language, and OCL-PS.
You may want to start at the beginning: Chapter 1, or see Chapter 3 (the previous chapter)
Video 4: Action Language and OCL-PS
To make your experience smooth, we set the main tags mentioned in the video to the right bar menu of this mini-player. Choose an interesting subtitle on the list and immediately get to the exact theme navigation item place in the video. Now you can pick any topic to be instructed on without watching the whole video.
Chapter 4: Seeker Forms, Search Expressions, and the OCL Debugger
106. Read the Manifest on our view of what a line of business application needs here: Getting to the bottom of the Line of Business Application
NOTE: Click on the step/number to access the corresponding images.
107. The Person ViewModel from Chapter 3 is a Document form. Now, we will look at a Seeker Form. Find AutoFormPersonSeeker, and open it in ViewModel Editor. Adapt this to make it your own.
Minor change: In the video, the system for the debugger starts when the "Local TurnkeyPrototyper" radio button is selected. You will need to switch the radio button to "XML" to start the debugger; otherwise, you will see a note saying "Turnkey is started with special button."
108. We are going to make this Seeker also search on Age. In order to do that, we need to take the search string and check that it is convertible to an Integer. The string '1' is convertible but the string 'One' is not.
- We can parse with the expression
Integer.Parse('1')
. - Start the debugger and try the expression. Verify that you get an answer of 1.
109. Check what happens if you do Integer.Parse('One')
. Confirm that you get a blank result.
110. A blank result is a null result. Null is different from zero - it is nothing, not even zero.
- We can check if the result is null with the isnull operator:
Integer.Parse('One').isnull
. Verify you get true. - Test
Integer.Parse('10').isnull
. Verify you get false.
111. Test Integer.Parse('123')
. Verify you get 123 back.
112. Test Integer.Parse(vANewVariable)
and verify you get an error due to missing variable declaration.
113. In the top left box, that says "Your variables", enter vANewVariable:String='456'
followed by return.
114. Test Integer.Parse(vANewVariable)
and verify you get 456.
115. Press the "Add Expression" button in the debugger to give you a new expression box and select it. Note the yellow "current" marking on the right of the expression box.
116. Switch the lower empty expression box to "Action".
- Action is slightly different from OCL because while Action can change data - OCL can only watch data. Use it as input and output a transformed result.
117. In the MDriven Action Language, there is an assign operator denoted by :=
.
- Test the assign operator by writing
vANewVariable:='200'
and executing the expression. - Note the output.
118. Go back to the expression box with Integer.Parse(vANewVariable)
.
- Notice the yellow marking changing.
- Execute the expression and note that the output is now 200.
119. Look in the top right-hand box in the debugger. Here you will find your variable and its current value.
120. We now know how to assign a value to a variable. Declare yet another variable in the top box vIntHolder:Integer=12
and end with a new line.
121. Test vIntHolder
in the top expression box; verify you get 12.
122. In the lower expression box that is set to "Action," try to assign the output to vIntHolder by typing vIntHolder := Integer.Parse(vANewVariable)
.
123. Check the vIntHolder
value in the top right box.
124. Since both the OCL and Action Languages are functional languages (they act as functions and functions ALWAYS return something that is ALWAYS of a known type), we sometimes want to ignore the result of a function, and instead, perform another function and rely on that other function's output. For this purpose, we have the action operator separator semicolon ( ; )
- just a single ;
.
- Let us try that in the Action expression. Type:
vIntHolder := Integer.Parse(vANewVariable);vIntHolder+1
- Note the result.
125. Switch back the lower expression box to OCL, execute the expression, and note the errors. This is due to the fact that OCL does not recognise the assignment operator :=
, nor does it recognise the separator operator ;
. These are only available in Action Language.
126. Now that we know about separator and Integer.Parse and assignment, we head back to PersonSeeker
. Right-click columns, add a new Action Column, and place the button in a conflict-free position (not blocking or covering another button).
127. Note that the search string in the column named "Filter" is assigned to the vSeekParam variable. In the New Button expression (since it is an action, we have Action Language in the expression), write Integer.Parse(vSeekParam)
.
128. Click the Green box header "PersonSeeker."
NB: May 16, 2024 - Recent changes to the MDriven Designer
- The left side now updates to show properties for this level of the ViewModel tree.
- Find and click the Variables and Validations fold button which now shows on the left. See the image below.
129. Press "Add Variable", call it vSeekIntValue
, make it type "Integer", and skip the initial value.
130. Head back to the NewButton expression and change it to vSeekIntValue:=Integer.Parse(vSeekParam)
.
- Verify that you do not have any errors in the ViewModel or in the model (save and check for the red dot). It is good to use the OCL editor to help find the correct syntax.
131. Add yet another ViewModelColumn, choose a GenericViewModel column, and place the box next to the button.
132. Set the expression of the new column to vSeekIntValue
and save.
133. Go to the web application, open the Seeker, and try to write "123" in the Filter box. Press your new button and check that the new column you added shows 123.
134. Write the text in the Filter, press your new button, and check the result in the new column. It should be null (empty).
135. We are now going to put this initiation of the integer value into the main search button. We do this by adding the vSeekIntValue:=Integer.Parse(vSeekParam)
before the current search expression:
vSeekParamWildcard:='%'+vSeekParam+'%';selfVM.Search
To hold the 2 expressions apart, we use the separator " ; "
Open up the action editor and make it look like this: vSeekIntValue:=Integer.Parse(vSeekParam);vSeekParamWildcard:='%'+vSeekParam+'%';selfVM.Search
Just for ease of reading, let's put a newline after each ;
vSeekIntValue:=Integer.Parse(vSeekParam); vSeekParamWildcard:='%'+vSeekParam+'%'; selfVM.Search
136. We now have a strongly-typed integer value in vSeekIntValue
and we will use this to compare age in the search criteria.
The Orange ViewModel classes in the ViewModel are called Search expressions. Search expressions use the third(and last) type of language in MDriven. We call this language OCL-PS, where PS is short for Persistent-Storage, i.e. the database. OCL-PS is important to large enterprise applications that may have millions of Person objects. We can use OCL - but it will not be as fast as if we meet the database halfway and talk to it in its own language. The language of the database is different depending on the type and brand of the database. Most large production-grade databases use a proprietary dialect of SQL. Since MDriven wants to work no matter what, we use OCL-PS which is then translated to the correct SQL or some other database language.
137. Select ViewModel class for Seeker expression (Orange) called seekCrit, select Crit1 within it, and change the expression from Person.allinstances
to Person.allinstances->select(p|p.Age=vSeekIntValue)
. This will search for persons matching a given age. Save and check the web.
138. Remove the active expressions of Crit1 to make your new seek expression have an effect.
139. Change the expression to Person.allinstances->select(p|p.Age>vSeekIntValue)
in order to search older than. Save and test the web.
140. Change the expression to Person.allinstances->select(p|p.Age>=vSeekIntValue)
in order to search older or equal than. Save and test the web.
141. Enter the Active expression vSeekIntValue.notnull
to make this expression active only when we have a number. Save and test.
142. Remove NewColumn and ActionColumn - they only helped us; they fill no function now.
143. Create a person that is called 123 and is 456 years old. Save.
- Create yet another person named Guy#5 and make him 130 years old.
144. Search for 123 and think about the result. Don't make any changes and press Search again. Think about the result.
145. Read this section: Seeker view
- Pay special attention to the section marked #4 which talks about batches of search expressions.