Working with CONDCHECK I got confused. The condition check works to mark a field that is filled out incorrectly, but the condition is to be read as “these conditions should be satisfied, if not…”.
Which makes sense; you write the condition that you want satisfied. If it isn’t you get the message.
My problem was that I thought of it in the context of if … then; if this condition is satisfied, I should get the message. Which I now realise was wrong.
I needed this, so here it is for posterity:
In the list BUTLST, I wanted to select the value from the field WCHAR36, on the entry where the value from the field BUTNR matched the mapped field IZBUTNR.
So, in sequence, I wanted
the list BUTLST
the value from the field WCHAR36
on the entry where the value from the field BUTNR
... lxml:list-entries/lxml:entry/lxml:column[@name='BUTNR'][text() ... ]
matched the mapped field IZBUTNR
... = key('field-value', 'IZBUTNR') ...
Completed that is
/lxml:data/lxml:lists/lxml:list[@name='BUTLST']/lxml:list-entries/lxml:entry/lxml:column[@name='BUTNR'][text() = key('field-value', 'IZBUTNR')]/../lxml:column[@name='WCHAR36']
Def_List Name(#BUTLST) Fields(#BUTNR #BUNAVN #WCHAR36) Type(*WORKING) Entrys(*MAX)
Web_Map For(*BOTH) Fields(#IZBUTNR #BUTLST )
I keep forgetting this, cause I do development in other languages and frameworks as well, and nothing in the LANSA editor stops me. But WAM command handlers must not have a name of more than 8 characters.
Or rather, it can and it will work, but then when you try to set it up in the VLF, you, again without warning, enter the more-than-8 character name and lo and behold, you end up with errors on your site.
Instead, a command handler named, for example, CH_FAKKOP, should be referenced in the VLF by the first 8 characters, CH_FAKKO, even though the WAM component is 9 characters.
Edit: This also applies to the WAM name in XSLT, like
<xsl:with-param name="on_change_wrname" select="'UHandleEvent'" />
<xsl:with-param name="on_change_wamname" select="'CH_FAKKO'" />
This is one of those issues that arise from me coming from a different background than what I imagine a typical Lansa developer, indeed a typical i series developer, come from. It is a useful reminder what decimals actually mean.
For example, I have a repository field that is defined like this:
Define Field(#JSN) Type(*SIGNED) Length(4) Decimals(2)
That means, a signed decimal value with 2 digits before the decimal point and 2 digits after the decimal point. In a function, I calculate the value and exchange it back to application calling. In that application, I (unfortunately) have an override, changing the number of decimals.
Override Field(#JSN) Decimals(1)
This was probably done to format the display of the value but where I imagined the value would be passed in a lower level format and then parsed in relation to the definition, this is not what happens.
Instead, the value is still the same 4 digits, but one of those that was after the decimal point is now before the decimal point. The value has been multiplied by 10^1; a value of 0.21 is now 2.1.
Because the override only moved the decimal point.
As someone mentioned a while back on the forum, getting a newline, or indeed any character from a character code, is difficult to find. But it is easy, once you know how:
returns a carriage return in ANSI. I’d probably prefer
(13).AsUnicodeString + (10).AsUnicodeString
as I am primarily targeting the Windows platform.
However, this is a solution for Lansa v. 14, not v. 12, where AsUnicodeString does not exist. In Lansa v. 12 you write
(13).AsByte.AsString + (10).AsByte.AsString
A quick follow-up on .IsValidPassword: The highest entropy of a password that would be accepted by .IsValidPassword(strong) can be calculated like this:
1 upper - 26 characters
1 lower - 26 characters
1 numeric - 10 characters
1 special - 7 characters
4 remaining - 26+26+10+7+1(space) = 70 characters
log2(26+26+10+7)*4+log2(26)*2+log2(10)+log2(7) ~~ 40 bits of entropy
If the requirement was simply 8 characters, the entropy could be
log2(70)*8 ~~ 49 bits of entropy
Entropy is used to calculate how long it would take to crack a password, provided it wasn’t an already know password:
Number of guesses = 2^(entropy - 1)
If we can make 1,500 guesses per second, divide by (1500 * 86400) (86400 is the number of seconds per day):
40 bits of entropy ~ 4,000 days
49 bits of entropy ~ 2.1 million days
What about words? Using words doesn’t necessary increase entropy, as words are part of a finite dictionary. The complete dictionary is somewhere between 100,000 and 200,000 but most people only use 3,000 words.
log2(3000)*4 ~~ 46 bits of entropy ~ 271,000 days
log2(3000)*5 ~~ 58 bits of entropy ~ 1.1 billion days
Using 4 words from your own dictionary would give a stronger password than what .IsValidPassword(strong) accepts, even if those 4 words would not get accepted by that method.
I am not impressed with the Lansa v. 14 SP2 addition of .IsValidPassword (see documentation):
I am sorry. This is completely insufficient and wrong. Also, this is no secret as everyone knows that these rules are insufficient and wrong. Or should know.
So, what are the right rules?
- Long passwords – this equals greater entropy
- Use words that can be remembered – this way the password doesn’t have to be written down or stored digitally
- Do not require use of mixed case and/or special characters – as this lowers entropy
A follow-up to this post, please note that strings can only take up to 65535 bytes at a time. However, #RESPONSE.ContentString appears to accept longer strings. The former is a problem, the latter is a feature.
This works, provided #TEMP_OUTPUT is never truncated:
#RESPONSE.ContentString += #TEMP_OUTPUT
Did I mention that the Lansa documentation is incomplete?
Problem: Create a simple server module to accept a bit of data and simply reply with a string. Let that data be set with querystring parameters.
If I wanted to send the data as parameters in a POST request I would just do this:
POST to http://[DOMAIN/BASEPATH]/w=[WEBROUTINE]&r=[SRVROUTINE]&vlweb=1&part=[PARTITION]&lang=[LANGUAGE]
with, for instance,
But if the client expects to be able to send the data as part of the querystring, in a GET request, I need to do this:
GET to http://[DOMAIN/BASEPATH]/w=[WEBROUTINE]&r=[SRVROUTINE]&vlweb=1&part=[PARTITION]&lang=[LANGUAGE]&f(FIELD1)=DATA1&f(FIELD2)=DATA2
I could not find that f(…) trick, putting the parameters inside the parentheses, in the documentation but a very lucky search on the forum helped me.
My sample server module looks like this:
Begin_Com Role(*EXTENDS #PRIM_SRVM)
Define Field(#PROC_OUTPUT) Type(*string) Length(65535)
Srvroutine Name(DATA) Response(#RESPONSE)
Field_Map For(*INPUT) Field(#FIELD1)
Field_Map For(*INPUT) Field(#FIELD2)
* do something with FIELD1 and FIELD2 here
#PROC_OUTPUT := "Done"
#RESPONSE.ContentString := #PROC_OUTPUT
Surprise! I am no friend of the Lansa documentation, so I thought I would add a few notes here.
I am grateful that there is an intrinsic function for floats as ArcTangent2, but which parameter is X and which is Y? The documentation is pretty sure that it is like this
#X.ArcTangent2( #Y ) /* not exactly... */
but I find that the parameters are reversed, if you take the thinking from elsewhere, like my previous programming experiences and for instance Wikipedia. A better explanation in the documentation could have helped me here, but I managed to find out that the problem was here. So I changed my code to
#Y.ArcTangent2( #X ) /* now similar to atan2(y,x) elsewhere */
Then comes the question of precedence… The difference between these two lines is obvious:
#A1 := (#DT / 2).Sine * (#DT / 2).Sine + #RT1.Cosine * #RT2.Cosine * (#DN / 2).Sine * (#DN / 2).Sine
#A2 := ((#DT / 2).Sine * (#DT / 2).Sine) + (#RT1.Cosine * #RT2.Cosine * (#DN / 2).Sine * (#DN / 2).Sine)
But I was surprised that they returned different results. I expected that both returned the same as the second one. Instead, the first returned the same as
#A3 := ((#DT / 2).Sine * (#DT / 2).Sine) + #RT1.Cosine) * (#RT2.Cosine * (#DN / 2).Sine * (#DN / 2).Sine)
I realize now that 1 + 2 * 3 in RDML(X) equals 9, whereas I would have expected 7 from my experience in many other languages. Now I know.