StreamLocation doesnt seem to affect where streams are stored
Hi-
I have a class that specifies that streams should be stored in SSA.DocumentCacheS, however, they are getting stored in CacheStream instead.
How can I get streams to properly store in SSA.DocumentCacheS?
Here's the section from my storage definition that shows the StreamLocation
<DataLocation>^SSA.DocumentCacheD</DataLocation>
<DefaultData>DocumentCacheDefaultData</DefaultData>
<IdLocation>^SSA.DocumentCacheD</IdLocation>
<IndexLocation>^SSA.DocumentCacheI</IndexLocation>
<StreamLocation>^SSA.DocumentCacheS</StreamLocation>
<Type>%Storage.Persistent</Type>But when I look at the globals created:
Global ^SSA.DocumentCacheD
^SSA.DocumentCacheD("997ey01BWB")=$lb("",$lb($lb($c(0,19,1,14,1)_"^CacheStream"_$c(3,4,2,2,1),,"^CacheStream")),$lb("Bronchitis.tiff"),$lb("8416350"))
Global ^SSA.DocumentCacheS [Global does not exist]
Global ^Any thoughts on where I went wrong?
Thanks
Comments
Please, what is definition of your stream property and how do you create its data?
If the stream is type of %Library.GlobalCharacterStream or %Library.GlobalBinaryStream, the location of the streams depends if you write data directly to the stream property or if you created the stream first and assign it to stream property:
Class tv.test Extends %Persistent,
{
Property MyStream As %GlobalCharacterStream;
}
USER>s x=##class(tv.test).%New()
USER>w x.MyStream.%Location
^tv.testS
USER>w x.MyStream.Write("My Data")
1
USER>w x.%Save()
1
USER>zw x.MyStream.GetStreamId()
$lb($c(0,16,1,11,1)_"^tv.testS"_$c(3,4,4,2,1),"%GlobalCharacterStream"
BUT:
USER>s x=##class(tv.test).%New()
USER>s str=##class(%GlobalCharacterStream).%New()
USER>w str.%Location
^CacheStream
USER>s x.MyStream=str
USER>w x.MyStream.%Location
^CacheStream
USER>w x.MyStream.Write("My Data")
1
USER>w x.%Save()
1
USER>zw x.MyStream.GetStreamId()
$lb($c(0,19,1,14,1)_"^CacheStream"_$c(3,4,2,2,1),"%GlobalCharacterStream")
Therefore if you do not want to change the location of the stream, is better to use CopyFrom method insterad:
USER>s x=##class(tv.test).%New()
USER>s str=##class(%GlobalCharacterStream).%New()
USER>w str.Write("My Data")
1
USER>w x.MyStream.CopyFrom(str)
1
USER>w x.%Save()
1
USER>zw x.MyStream.GetStreamId()
$lb($c(0,16,1,11,1)_"^tv.testS"_$c(3,4,5,2,1),"%GlobalCharacterStream")
Please, let us know if it corresponds to your findings.
@Tomas Vaverka
Ahoi, can you watch my local terminal from remote?
You describe pretty much my investigation! ![]()
Hi Jenna,
I took some time to verify my suspicion. (Caché 18.1)
You depend on the type of stream that is used in your object
#A) %Library.GlobalBinaryStream or %Library.GlobalCharacterStream
- if you have no stream yet you run do obj.MyStream.Write("whatever")
then your stream will land in ^SSA.DocumentCacheS as expected - but if you get an already existing external stream and set obj.MyStream = myStreamOrefthen just the oref / OID of the stream is set including ^CacheStream.
Which seems to be your case ![]()
![]()
it's not a big surprise as ENSEMBLE may still use the old style.
#B) using %Stream.GlobalBinary, ...
- Both cases ended as expected with the stream in ^SSA.DocumentCacheS
It seems to me that a CopyFromStream happens during the assignment.
I'd name it expected behavior.
I started with %Stream.GlobalBinary, ... wondering what the problem might be.
Thinking over ENSEMBLE I moved to %GlobalBinaryStream
My stream definition is
Property Streams As list Of %CSP.CharacterStream;
I used the %CSP.CharacterStream because that is what was being created in the %request object and I figured it would be simpler to just add that stream to my collection.
I understand why this would be stored in CacheStream as it it created by the CSP engine. I think my solution is to use a %Stream.Character and actually copy the contents from the %CSP.CharacterStream rather than storing itself.
you are fully right.
I just checked in Class Reference:
stream class %CSP.CharacterStream extends %GlobalCharacterStream, %CSP.Stream