Bug #6412
implement BUFFER:KEYS attribute
100%
History
#2 Updated by Constantin Asofiei almost 2 years ago
There is this abend as BufferImpl does not implement 'Keyable' methods:
java.lang.AbstractMethodError: Method com/goldencode/p2j/persist/$__Proxy1226.keys()Lcom/goldencode/p2j/util/character; is abstract at com.goldencode.p2j.persist.$__Proxy1226.keys(Unknown Source)
#3 Updated by Constantin Asofiei almost 2 years ago
BufferImpl
:
- The type
BufferImpl
must implement the inherited abstract methodKeyable.keys(long)
- The type
BufferImpl
must implement the inherited abstract methodKeyable.keys(NumberType)
- The type
BufferImpl
must implement the inherited abstract methodBuffer.querySynchronize()
- The type
BufferImpl
must implement the inherited abstract methodIterableResource.setCurrentIteration(handle)
- The type
BufferImpl
must implement the inherited abstract methodKeyable.keys()
#4 Updated by Ovidiu Maxiniuc almost 2 years ago
- % Done changed from 0 to 50
- Status changed from New to WIP
I am about to finish the implementation of the missing methods.
#5 Updated by Ovidiu Maxiniuc almost 2 years ago
- Status changed from WIP to Review
- % Done changed from 50 to 100
Some notes about the revision:
CURRENT-ITERATION
returns an INTEGER for BUFFER not a HANDLE. I do not know how we can detect and resolve this at conversion time if all we have is a HANDLE. It is a read-only attribute and I implemented the setter. However, the name of the setter must be changed tocurrentIteration()
instead ofsetCurrentIteration()
. I cannot return an integer at this time.- I had some difficulties working with buffers. In fact this was my great time consumer. The fix was simple, just inserting the
.ref()
. The problem was that the debugger showed me the object structure correct before calling a method but when the method was invoked (using proxy), the object was 'garbaged'; - there was a problem handling the buffers lists in dynamic query handler. Because they were added twice, a circular loop was created leading the application freeze when this tree was navigated;
- I noticed that the static data-source's name was not initialized at all. Fixed it.
#6 Updated by Constantin Asofiei almost 2 years ago
Ovidiu, I don't think the implemention is correct.
If there are no defined key fields, this attribute returns a comma-separated list of key fields in the buffer’s unique primary index (if any). If there are no defined key fields and no unique primary index, this attribute returns the string "ROWID".
There is application logic which looks into the KEYS fields, and if there is none, you return ROWID
... there is no such field.
#7 Updated by Ovidiu Maxiniuc almost 2 years ago
Ovidiu, I don't think the implemention is correct.
The implementation is based on testcases. Like this:
DEFINE TEMP-TABLE t3t FIELD f2f AS INTEGER.
MESSAGE BUFFER t3t:KEYS.
will print rowid
(in lowercase).
However, if you construct a buffer with rowid as keys in a dataset, the method will return ROWID
, in uppercase. Strange.
#8 Updated by Constantin Asofiei almost 2 years ago
Add a unique, primary (and combinations of unique or not, primary or not) index and see what happens. My patch is this:
### Eclipse Workspace Patch 1.0 #P p2j6129a Index: src/com/goldencode/p2j/persist/BufferImpl.java =================================================================== --- src/com/goldencode/p2j/persist/BufferImpl.java (revision 3634) +++ src/com/goldencode/p2j/persist/BufferImpl.java (working copy) @@ -4641,6 +4641,31 @@ @Override public character keys() { + if (parentDataSource == null || keys == null) + { + // get the primary unique index + int idxNo = 0; + TableMapper.LegacyIndexInfo index = TableMapper.getLegacyIndexInfo(buffer(), idxNo); + while (index != null) + { + if (index.isUnique() && index.isEffectivePrimary()) + { + String bufKeys = ""; + for (String key : index.getComponents()) + { + if (!bufKeys.isEmpty()) + { + bufKeys += ","; + } + bufKeys += key; + } + + return new character(bufKeys); + } + index = TableMapper.getLegacyIndexInfo(buffer(), ++idxNo); + } + } + if (parentDataSource == null) { return new character(DataSource.ROWID_KEY); @@ -4654,6 +4679,11 @@ StringBuilder sb = new StringBuilder(); for (String key : keys) { + if (Session.PK.equals(key)) + { + continue; + } + if (sb.length() != 0) { sb.append(",");
#9 Updated by Ovidiu Maxiniuc almost 2 years ago
I see. The implementation was incomplete. Thank you for noticing that.
I used your patch to fix the issue. Notice that using the TableMapper
implies a double map lookup. The preferred approach is to access the DMO metadata directly.
Committed as r13894.
#10 Updated by Constantin Asofiei almost 2 years ago
- Status changed from Review to Test