OE11, windows 7
given this code:
class1
class temp.class1:
def temp-table TTBug no-undo serialize-name "IsThisABug"
field field1 as character
field field2 as character
field field3 as character.
method public void Bind(output table TTBug bind):
end method.
method public void foo():
find first TTBug.
message "In class1" skip
"field1" TTBug.Field1 skip
"field2" TTBug.Field2 skip
"field3" TTBug.Field3 skip
view-as alert-box.
end method.
end class.
class2:
class temp.class2:
def temp-table TTBug no-undo serialize-name "IsThisABug" reference-only
field field1 as character
field field3 as character
field field2 as character.
method public void foo():
def var class1 as temp.class1 no-undo.
class1 = new temp.class1().
class1:Bind(output table TTBug bind).
create TTBug.
assign TTBug.field1 = "field1"
TTBug.field2 = "field2"
TTBug.field3 = "field3".
message "In class2" skip
"field1" TTBug.Field1 skip
"field2" TTBug.Field2 skip
"field3" TTBug.Field3 skip
view-as alert-box.
class1:Foo().
end method.
end class.
run this code:
(NEW temp.class2()):foo().
Ouch. Take you long to find?
Looks like a bug to me. Compiler complains when you change the type or name of field3.
-- peter
in a word, yes.
I simply could not understand why the data was ok. Then it wasn't.
I suspect that either the buffer allocation is wrong , should be using field name not field position in the table, or the compiler should determine that the definitions are not the same.
Either way, it was an , errm, interesting few hours ..
Having the field names and their data being the same, couldn't've helped much
(I know that's the repro).
For the record, below are screenshots of the messages. Note the content of field2 between the 2 classes.
Message was edited by: Peter Judge: email reply didn't include the messages
Yeah, the real world case actually had nearly a dozen fields, with two swapped round (BuildUnitGUID and AccessMode)
So , whenever I updated some data, the BuildUnitGUID got allocated to "public" (which was the content of the AccessMode field), which then meant that nothing was linked to the parent table anymore, and *poof* , as if by magic, all children disappeared from the xml file
Seems like another argument for only having the TT in one place ....
jmls wrote:
in a word, yes.
I simply could not understand why the data was ok. Then it wasn't.
I suspect that either the buffer allocation is wrong , should be using field name not field position in the table, or the compiler should determine that the definitions are not the same.
Either way, it was an , errm, interesting few hours ..
So, some further feedback. First, some info on the cause of the behaviour from a core developer
The CRC that we keep to show that it is ok to bind the two tables only cares about the extent and datatype of the columns, and the indexes. If those match, then it allows the binding. It does not even look at the field names themselves.
And second, this is not currently considered a bug
Or - which involves less of an architectural change - that EVERY temp-table and ProDataset definition belongs into an include file with parameters for
- access member (PROTECTED / PRIVATE)
- REFERENCE-ONLY
- before-table (yes/no)
- name prefix
So, some further feedback. First, some info on the cause of the behaviour from a core developer
The CRC that we keep to show that it is ok to bind the two tables only cares about the extent and datatype of the columns, and the indexes. If those match, then it allows the binding. It does not even look at the field names themselves.
I just had a quick look in to online help - but is there some reference on this CRC calculation somewhere?
I didn't find anything.
I must say, I agree to Julian, that this smells buggy. The behaviour is so unexpected, that I'd consider it a bug as well. If it's not documented somewhere.
Bottom line, if it behaved properly, then there would be no bug to fix, but since it is not well-behaved and no warning is given, then, perforce, it must be a bug.
pjudge wrote:
So, some further feedback. First, some info on the cause of the behaviour from a core developer
The CRC that we keep to show that it is ok to bind the two tables only cares about the extent and datatype of the columns, and the indexes. If those match, then it allows the binding. It does not even look at the field names themselves.
And second, this is not currently considered a bug
First - changing the name of the field does matter (see your previous post) - so it *does* look at the field names themselves
Second: you have to be kidding. Anything that corrupts data (and, yes, I consider this as a corruption as in my case the unique key guid was magically transformed into "public", without me lifting a finger) _has_ to be considered a bug.
I very rarely say this is public - Progress is way wrong here. This smells like the old "that's a documentation error" rather than actually conceding that a bug exists.
As you know, I *hate* include files. With a passion.
However, in this case, I may have to concede and agree with you.
Ouch. That hurt.
I'll spend you a beer at the PUG Challenge Americas to relief you from the pain.
The pain is so intense I fear that it will take at least a dozen beers to releive it ....
As you know, I hate include files. With a passion.
However, in this case, I may have to concede and agree with you.
Ouch. That hurt.
Which part? Agreeing with Mike, or using include files?
Can you generate the TT defs?
-- peter
The pain is so intense I fear that it will take at least a dozen beers to releive it ....
I it's Bud light, that's understandable.
pjudge wrote:
Which part? Agreeing with Mike, or using include files?
Can you generate the TT defs?
-- peter
1) I agree with Mike on a lot of things. Apart from .net. and include files ...
2) I am doing now. My problems were caused by having to bootstrap Maia using Maia. So I had to hand-code until it could generate it's own code ...
if it's bud lite, then that will simply cause more pain. Although I have been reliably informed that there is a great selection of decent beer at Pug challenge
You could agree with me, instead, and that would spare you the include file ... but might be even more painful!
You could agree with me, instead, and that would spare you the include file ... but might be even more painful!
So when it's even more pain, why go that way? Are you offering more beer?
Although I have been reliably informed that there is a great selection of decent beer at
Pug challenge
Yep: Bud Light, Miller Light, Coors Light. And Natty Ice if you're lucky.
Aaaaannnnnnd I think that was the sound of my registration being revoked
-- peter
You could agree with me, instead, and that would spare you the include
file ... but might be even more painful!
This may not be the correct forum, but can you clarify something?
Let's take a CustomerTable class that defines a tt.
define protected temp-table ttCustomer no-undo
field CustNum as int
field Name as char
.
End class.
Q1. Is this CustomerTable the message (or part of it) that gets passed around from client to server? Between server layers (BE-> DA -> DS) too?
Q2. How do I attach logic/code to it? Inheritance ("Class CustomerModel inherits CustomerTable" or " Class CustomerBusinessEntity inherits CustomerTable") or decoration or some other mechanism? Important here is the ability to write static code (FOR EACH ttCustomer) in this logic.
-- peter
We probably are diverting the thread a bit, but ...
For the first question, I think it is important to distinguish the TT from the message. The message may be many, many things depending on context. In particular, in most cases there is no reason to pass the whole contents of the data from one session to another. One might pass in or out a single instance, but not the whole table. The one obvious *possible* exception to this is the special case of needing to populate a client side browser with a body of data. Even then, one may not send the entire table, but only one visible set at a time. Even when whole sets of data are to be sent, I would distinguish between the message and the TT in which they are going to be held at either end, rather than simply passing the TT itself.
I am not sure of the issue you are trying to raise in Q2. For starters, I would not have a "CustomerTable" class. I would have a class that had a particular purpose that happened to use a TT as the internal structure for storing the data elements of the class. E.g., one might have a state code validation class which had a TT of valid state codes and names. The TT is invisible from the outside; all one knows that one can submit a state code and get back a name or an error message that the code is not valid. Whether the inside is a TT, array, linked list, or whatever is not a visible part of the class.
Given classes which have a purpose and some BL and happen to use a TT to hold the data, I'm not sure what your issue is about attaching logic. E.g., I recently had a need for a class which would create and manage a list of files below a specified starting directory. I created a superclass which had all of the logic for managing the file list and nexting through it and subclasses which overrode one method to determine what types of files were included in the list. This means that all the logic for what might be a site-specific set of criteria, e.g., "how do I recognize what files are compile units?" is in a very small subclass separate from the mechanics of managing the list.