Table Of Contents....
OWA Blobs
Have you ever wanted to store a blob in the database,
say an image or a spreadsheet, and retrieve it easily via the Oracle Web
Server? Have you ever wanted to use the web to upload an image/document/whatever
directly into the database or into the file system?
If so, you are in luck.
We have developed two web agent 'replacements' called
-
OWAI
Oracle Web Agent Image for downloading blobs from the database
-
OWAUP
Oracle Web Agent Upload for uploading blobs into the database and invoking
an existing web agent routine (pl/sql) to further process the information
HOW it works:
Blob downloading
Blob downloading is straight forward. We have a table with a unique primary
key (NAME) and three dependent fields, IMG_SIZE, MIME_TYPE, and IMAGE.
The owai program (the download program) will take the NAME sent to it in
the PATH_INFO variable and use that to perform an indexed read into the
image table. This will fetch the MIME_TYPE, and IMAGE for that unique name
out.
The OWAI routine will verify the MIME_TYPE in the database table against
the list of valid mime types in the svXXXX.cfg file and if the mime_type
does not exist in that file, will use the default mime type for that file
type (it will use the URL and the extension in the URL to decide what mime
type to associate with this request). So, the OWAI program will print out
a mime header using the included mime_type field, for example:
Content-Type: image/gif
The OWAI program will then piece wise fetch the IMAGE column blob out of
the table.
How to apply compression for downloads
If you use owaigz instead of just owai, pkzip compatible
compression will be applied to the data stream. The mime type application/x-gzip
will be associated with the downloaded file.
For example, if you enter the following URL:
http://yourhost/someWebAgentName/owai/MySpreadSheet.xls
The following will happen:
-
The owai program will be executed
-
It will discover its web agent name to be "someWebAgentName"
-
It will locate the owa.cfg file and parse it to discover what it means
to be someWebAgentName
-
It will use the same rules that owa uses to figure out if the current listener
is a valid listener for this service
-
It will log into the database
-
It will use the PATH_INFO variable which will be set to MySpreadSheet.xls
to issue the following query: "select img_size, mime_type, rowid from image
where name = 'MySpreadSheet.xls'". It uses bind variables for this query,
not the constant
-
It prints out the content-type and the blob itself
-
It piece wise fetches, 64k at a time, the blob and writes it back to the
client
And if you enter the following URL:
http://yourhost/someWebAgentName/owaigz/MySpreadSheet.xls
The following will happen:
-
The owaigz program will be executed
-
It will discover its web agent name to be "someWebAgentName"
-
It will locate the owa.cfg file and parse it to discover what it means
to be someWebAgentName
-
It will use the same rules that owa uses to figure out if the current listener
is a valid listener for this service
-
It will log into the database
-
It will use the PATH_INFO variable which will be set to MySpreadSheet.xls
to issue the following query: "select img_size, mime_type, rowid from image
where name = 'MySpreadSheet.xls'". It uses bind variables for this query,
not the constant
-
It prints out the content-type and the blob itself
-
It piece wise fetches, 64k at a time, the blob. Each chunk is compressed
and written it back to the client
Blob Uploading
Blob uploading is somewhat less straight forward. We are making use of
a 'new' feature in HTML. If you build forms, then you know the following
code:
<form action=foo method=post>
<input type=submit>
</form>
That will cause all of the variable/value pairs from the form to be pushed
onto the stdin of the cgi-bin program. The information will be 'escaped'
(for example a space will be turned into a '+' and so on). This works fine
for ascii text data, but not so well for lots of binary information.
What the owaup program makes use of is an extension on the form tag
as follows:
<form action=/someWebAgentName/owaup/foo method=post enctype="multipart/form-data">
<input type="file" name="p_file">
<INPUT TYPE="submit" >
<FORM>
This creates a form that looks like: There are two new features here. One is the
multipart/form-data attribute on the form tag. The other is the
input type=FILE tag. The multipart/form-data attribute causes the
information from the form to be encoded in a fashion very different from
the GET or the POST methods. It is encoded similar to the way a "multi-part,
mime encoded" email would be sent. The normal Oracle Web Agent does not
handle this type of data stream (and will crash if it is sent to it). That
is where the owaup program comes in. It correctly interprets and parses
the data stream and sends it to the pl/sql code. The input type=file tag
simply allows the client to use the browser to browse their file system
and pick files.
To see the flow of the data, lets assume on the above form you filled
it in and pressed the submit button. Then what would happen is:
-
The browser would read in your file locally
-
The browser would encode the information and all other form fields into
something that looks like an email message
-
The browser sends that to the web server
-
The web server runs the owaup program
-
It will discover its web agent name to be "someWebAgentName"
-
It will locate the owa.cfg file and parse it to discover what it means
to be someWebAgentName
-
It will use the same rules that owa uses to figure out if the current listener
is a valid listener for this service
-
It will log into the database
-
It will read the encoded data stream and break it into Variable/Value pairs.
When it finds a file in the encoded stream it will
-
Extract the file from the stream
-
Insert it into the IMAGE table. It will uniquely name this file using the
img_seq sequence number
-
Remove the file from the data stream and replace it with the unique name
-
After all of the variable/value pairs have been extracted, a pl/sql call
will be constructed. This is done by
-
Taking the pl/sql routine name from PATH_INFO
-
Creating a bind variable holder for each of the variable names discovered
in the above steps
-
Binding the values to each of the bind variables
-
executing the pl/sql routine
-
using the owa package to 'get_page' the output to print back to the web
browser
In short, your pl/sql routine will get a NAME of a file instead of the
file itself. The NAME of the file is used as a primary key into the IMAGE
table. You can link to the image table or do whatever you want to it.
Note, the insert of the file(s) into the database is part of
your transaction. If your procedure rolls back, it will be un-inserted.
If you commit, it will be commited.
How to upload to the file system
Uploading to the file system is quite easy. The logic is to look for a
variable named webAgentName_filedir variable in the svXXXX.app file.
This variable has the following meaning:
| webagentName_filedir |
NO |
If you want uploaded files to go into a file system subdirectory for
a given web agent instead of INTO the database, you will set this variable.
You will not set 'webagentName' but rather replace that with the name of
your DCD. For example, to allow ows-bin to upload files into the subdirectory
/tmp/ows-bin you would:
ows-bin_filedir = /tmp/ows-bin
Please note the lack of a trailing directory separator, it is intentional.
Don't put a trailing / or \ on the directory name. |
This will cause the uploaded files to be written into that directory. The
files will still be uniquely named by this function (eg: they will still
be named U1234567.ext where U is constant, 1234567 is a sequence that starts
at 1 and is zero padded, and .ext is the original file extension of the
uploaded file).
Currently, this works at the web agent level. A web agent (DCD) will
either save files into the database or they will save them into this directory.
You may have more then one filedir variable in your svXXXX.app file
but you should have only one per webagent. For example:
ows-bin_filedir = /tmp/ows-bin-stuff
owa_dba_filedir = /tmp/owa_dba_stuff
is ok.
How to upload/dnload to/from something other then the IMAGE table
This too is quite easy. The default table name for storing and retrieving
images will continue to be 'IMAGE'. Image is a table defined in owarepl/sql/image.sql
with the following structure:
create table image
(
NAME VARCHAR2(255),
MIME_TYPE VARCHAR2(30),
IMG_SIZE NUMBER,
IMAGE LONG RAW,
constraint image_pk primary key( name )
)
pctfree 0
/
With previous versions, this table name was constant. Starting with release
1.2, you may override this name and make it be any value Oracle Tablename.
Please note that the names of the columns within the table and their datatypes
remain constant. You may take the above create table statement and change
the name of the image table but leave the column definitions intact.
| webagentName_image_tname |
NO |
If you want to rename the IMAGE table that the upload/download code
uses. This variable setting will override the default of "IMAGE". For example,
if you wanted your ows-bin webagent to save uploaded images into the table
named foobar, you would:
ows-bin_image_tname = foobar
Please note the lack of a qualified username is intentional. Don't put
a username on this tablename, the cartridge will always put the username
of the webagent on the tablename to qualify it. |
How to upload/dnload to/from an Oracle8/8I BLOB type (not long raw)
This too is quite easy. The default table for storing and retrieving images looks like:
create table image
(
NAME VARCHAR2(255),
MIME_TYPE VARCHAR2(30),
IMG_SIZE NUMBER,
IMAGE LONG RAW,
constraint image_pk primary key( name )
)
pctfree 0
/
All you need do is create the table with the IMAGE column being a BLOB
type instead of long raw and then set the following svXXXX.app/wrb.app
configuration parameter:
| Parameter Name |
Mandatory |
How to use it |
| webagentName_use_lob |
NO |
set it equal to the single character Y. For example if you wanted
your ows-bin webagent to use a table with a blob, you would:
ows-bin_use_lob = Y
We will then use dbms_lob.read/write to access this column |