Sunday, September 18, 2011

Oracle OrdAudio and Grails

Recently I have started prototyping some web applications on Grails that uses the Oracle interMedia capabilities. One of the key problems is that you cannot use GORM to define a property which is an Oracle OrdMedia component, such as OrdAudio. I needed a way to stream out the audio data stored in this field in an Oracle database for which I created a Controller in Grails. But how do you retrieve the field object ?

Firstly I used Groovy SQL to get hold of the field by doing the following:

import groovy.sql.Sql

class StreamingController {
def sessionFactory

def index = {
String sqlstr = "select audio_file table where id = ?"
Sql sql = new Sql(sessionFactory.currentSession.connection())
sql.eachRow(sqlstr,[params.id]) { row ->
println row[0]
}
}
}

Invoking the "streaming" url, Grails report that the row[0] is a oracle.sql.STRUCT object. So how do I convert that into an OrdAudio object ?

Turns out that Oracle uses a Factory to build the OrdAudio object from the STRUCT.

sql.eachRow(sqlstr,[params.id]) { row ->
oracle.sql.STRUCT str = row[0]
oracle.sql.CustomDatumFactory factory = oracle.ord.im.OrdAudio.getFactory()
oracle.ord.im.OrdAudio audio = factory.create(str, java.sql.Types.STRUCT)
...
}

So you now have the OrdAudio object for which you can check its properties or extract the audio data out. If the data is stored in the BLOB, then you will use:

InputStream inp = audio.getDataInStream()

If the data is stored in a BFILE, then you will use:

oracle.sql.BFILE bfile = audio.getBFILE()
bfile.open()
InputStream inp = bfile.getBinaryStream()

You can then stream the data into the "response.outputStream" using the write method.