Question
· Mar 30, 2020

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

Discussion (6)2
Log in or sign up to continue

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.

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 = myStreamOref then just the oref / OID of the stream is set including ^CacheStream.

Which seems to be your case   sadcrying​​​​​​​  angry
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.   smiley

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.