Perspective save getBytes() into parameters as ArrayWrapper

When I call the getBytes() on a perspective file upload I get the expected type of array.array. However if I move that getBytes() array to a param and then look at the ensuing type I get com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper$ArrayWrapper.

How to I then take that param and later form it back to an array so I can pass it off to SQL to save as a longblob/varbinary(MAX)?

Based on this:

https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.0/com/inductiveautomation/perspective/gateway/script/PropertyTreeScriptWrapper.ArrayWrapper.html

, you can’t get to the original array again. ):

However, jython is often smart enough to construct raw java byte arrays when passing sequences into java APIs. Meaning, you might just be able to pass it to a PrepUpdate() and let JDBC have at it.

Otherwise, you’ll have to use the jarray module to reconstruct the plain byte array again.

So I ended up figuring it out after another cup of coffee.

I wrapped the param in list() and the JDBC driver was able to interpret what I wanted it to do thankfully.

Sucks that once it hits the params we can get it back to the original datatype. Oh well.

Spoke to soon. As a list it didn’t go into the database as a blob so I couldn’t pull it back out as a usable file. So back to the drawing board…

Pass the wrapper (which implements a python sequence) to the jarray module with the 'b' type code.

BTW, why do you put it in a param? Unless it is private, that will make it go back to the browser, but as json. Blegh. Cache it in a script module dictionary if you can’t send it directly to the database. That’ll keep it in the gateway as a normal byte array.

1 Like

No real good reason why. I just familiar with the params and it makes things a bit easier.

For the second option would it be as simple as this?

_fileBytes = []
def fileBytes()
    return _fileBytes

and then just use it as:

shared.fileBytes().append(newFileBytes)

Or am I missing something?

Yes, but you’ll probably want a .clear() in there. Also note that doing it just like that will have it shared across all sessions. You probably want a dictionary at the top level with session ids for keys, and save a (timestamp, bytes) tuple. Then use a gateway timer to clean out stale entries.

1 Like

Thanks for the help!

The jarray worked and so I know proof of concept is sound. So I’ll start working on the better alternative solution.

Also note that you don’t need a function to gain access to the top-level object. If you have this in myModule:

fileBytesMap = {}

You can just access myModule.fileBytesMap[someKey] anywhere.

2 Likes

Cool… didn’t know that.