Chapter 6. Loading Media

A very important consideration in a database-backed media application is how the data is loaded into the database. Depending on where the data comes from, and who is responsible for loading it, very different methods will be optimal. For example, an online photo album application will have very different loading requirements than a bank check image electronic storage and transmission application.

In the photo album example, it is clearly necessary to have users upload their pictures from their browsers or a custom desktop application that can batch an upload of a large number of pictures. Most photo album applications provide both.

In the batch processing environment of digitally scanning bank checks and storing them, the volume of data is critical and must be addressed. Loading the media will likely involve multiple streams of data that may need to load tens of thousands of checks per hour. Once in the database, these checks can then be transmitted for digital clearance or displayed to users from their online banking application.

In this chapter, we will look at various ways of loading interMedia data into the database.

PL/SQL

We have seen previous examples of loading data using PL/SQL from the file system in introductory sections. In this section we will look in more detail about using interMedia to load data using PL/SQL. We will not be describing nondatabase storage, except in the context of preparation to load the media into the database. Some of the features of loading using interMedia PL/SQL methods include:

  • Supports and has many media-specific methods available to create or modify media objects.

  • Uses methods, for example, setProperties(), setMimeType(), and so forth, to set attributes.

  • Provides an interface that may already be familiar to SQL users.

  • Provides immediate error feedback when procedures are compiled interactively from SQL.

  • Requires target media stored in file systems to be on a device that is local to the database server.

  • Sets image attributes in the import() method with an automatic call to the setProperties() method (for supported formats).

  • Sets audio, video, and supported media data attributes, but not automatically as part of the import() method. The script must call the import() method and call the setProperties() method.

interMedia object methods can be used to load multimedia data from the following data sources:

  • A media file from the file system

  • Media from the Internet using HTTP

  • Media using a custom data source plug-in

Loading from Local Files

Most users will be concerned with loading media from files. Please note that the files must be local to the database computer file system, not to where a user is running PL/SQL.

For an HTTP source, the images are pulled from websites using HTTP requests, not being pushed into the database from forms submitted by users. This could be useful in creating an archive of images from the database.

If the user has specialized requirements, like pulling and/or pushing image data from a proprietary image archive only accessible from an API, a custom data source plug-in may be written by the user.

Here is an example of loading an image, audio, and video onto the database into the same row from files local to the database server.

DECLARE
  img ORDImage;
  aud ORDAudio;
  vid ORDVideo;
  ctx RAW(64) := NULL;
  row_id urowid;
BEGIN
  -- Insert a new row into the pm.online_media table
  DELETE FROM pm.online_media WHERE product_id = 3003;
  INSERT INTO pm.online_media
         (product_id,
          product_photo,
          product_audio,
          product_video)
  VALUES (3003,
          ORDImage.init('FILE', 'MEDIA_DIR', 'laptop.jpg'),
          ORDAudio.init('FILE', 'MEDIA_DIR', 'laptop.mpa'),
          ORDVideo.init('FILE', 'MEDIA_DIR', 'laptop.rm'))
  RETURNING product_photo, product_audio, product_video,
rowid
  INTO img, aud, vid, row_id;

  -- Bring the media into the database and populate
  -- the attributes
  img.import(ctx);
  -- ORDImage.import also calls ORDImage.setProperties;

  aud.import(ctx);
  aud.setProperties(ctx);

  vid.import(ctx);
  vid.setProperties(ctx);

  -- update the table with the properties we have extracted
  UPDATE pm.online_media
  SET    product_photo = img,
         product_audio = aud,
         product_video = vid
  WHERE  rowid = row_id;

  COMMIT;
END;
/

Note that the image does not require a setProperties() method call since this is done implicitly.

Loading from an HTTP Source

For an HTTP source, the images are pulled from websites using HTTP requests, not being pushed into the database from forms submitted by users. This could be useful in creating an archive of images from the database.

Loading from an HTTP source is very similar to loading from a file source. The only difference is that the location of the data is specified differently. However, you may need to set some additional parameters using the utl_http package. In the following example the proxy server is set to wwwproxy.acme.com on port 80 except for computers in the *.acme.com domain.

DECLARE
  img ORDImage;
  thumbnail ORDImage;
  ctx RAW(64) := NULL;
  row_id urowid;
BEGIN

  utl_http.set_proxy('www-
proxy.us.acme.com:80','*.us.acme.com'),

  INSERT INTO photos
         (id,
          description,
          location,
          image,
          thumb)
  VALUES (202,
          'Goats',
          'Fields in Maine',
          ORDImage.init(),
          ORDImage.init())
  RETURNING image, thumb, rowid INTO img, thumb, row_id;

  -- Bring the media into the database and populate
  -- the attributes
  img.importFrom(ctx, 'HTTP',
                      'www.oracle.com/admin/images','oralogo.gif'),

  -- ORDImage.import also calls ORDImage.setProperties;

  img.processCopy('fileFormat=JFIF maxScale=128 128',
  thumbnail);

  -- Update and commit the row
  update photos set image=img, thumb=thumbnail where rowid
  row_id;
  commit;

END;
/

You can see that the difference is mostly how the image source is specified. For an HTTP source we specify the type as 'HTTP', the Web server (without the http://), and Web server path as ‘www.oracle.com/admin/images’, and the endpoint as the file 'oralogo.gif'.

Loading from a User Written Source

If the user has specialized requirements, like pulling and/or pushing image data from a proprietary image archive only accessible from an API, a custom data source plug-in may be written by the user.

Unrecognized Formats

Because of the rich plethora of media formats that exist, both proprietary and public domain, old and new, it may be the case that when loading media data into the database, the format of the media is not recognized by interMedia. In this case, the user may have to set metadata about the media manually. The most important information to gather is the MIME type of the media. This can typically be determined by either file extension, or for HTTP data, the MIME type passed as part of the HTTP response in the Content-Type header field.

You may also want to avoid the processing of the media data that determines the metadata for performance reasons. You may already know what type of data is being inserted, and either know other metadata or simply be uninterested in fully specifying the full metadata. For example, if you are batch loading check images that are always the same height, width, and MIME type, and that is all the metadata you are interested in, you can set this metadata manually and avoid the extra overhead of the setProperties method. Time-based media types may require scanning the entire data stream to collect metadata.

The image import method is slightly different from the import methods used by audio, video, and document objects. If used without extra parameters, or without metadata, it will perform a setProperties implicitly.

The following example shows an image object being loaded into the database, setting the type of the media manually.

create or replace procedure upload_image_noset
     (file_name varchar2,
     prikey_id number,
     descr varchar2,
     loc varchar2)
as
    imgobj        ORDSYS.ORDImage;
    ctx       raw(64):=null;
    thisrowid urowid;

BEGIN
    insert into photos t (id, description, location,
        image, thumb)
          values (prikey_id, descr, loc,
                   ORDSYS.ORDImage.init(),
                   ORDSYS.ORDImage.init())
        returning rowid, t.image into thisrowid, imgobj;

    -- Make Sure import does not call setProperties
    imgobj.fileFormat := 'OTHER';

    imgobj.importFrom(ctx, 'FILE', 'IMAGEDIR', file_name);

    -- Set the properties manually
    imgobj.mimeType := 'image/vnd.fujixerox.edmics-rlc';
    imgobj.height := 321;
    imgobj.width := 123;

    update photos t set t.image=imgobj where rowid =
     thisrowid;
END;
/

It may also be that only a portion of the images you are loading cannot be recognized. In this case, you may want to catch the exception and set MIME type metadata information explicitly as in the following example.

create or replace procedure upload_image_setmime
     (file_name varchar2,
     prikey_id number,
     descr varchar2,
     loc varchar2)
as
    imgobj       ORDSYS.ORDImage;
    ctx          raw(64):=null;
    thisrowid    urowid;
    ext          varchar2(10);
BEGIN
    insert into photos t (id, description, location, image,
thumb)
          values (prikey_id, descr, loc,
                   ORDSYS.ORDImage.init(),
ORDSYS.ORDImage.init())
        returning rowid, t.image into thisrowid, imgobj;


    BEGIN
       imgobj.importFrom(ctx, 'FILE', 'IMAGEDIR', file_name);


    EXCEPTION
      WHEN OTHERS THEN
        -- Is this an unsupported format error?
        if (INSTR(sqlerrm, 'IMG-00705') != 0) then
            -- Metadata cannot be automatically set. Try and
            -- set mimetype by file extension
           ext := SUBSTR(file_name, INSTR(file_name,'.'));
           if (UPPER(ext) = '.RLC') then
             imgobj.fileformat := 'OTHER';
             imgobj.import(ctx);
             imgobj.setMimeType
                 ('image/vnd.fujixerox.edmics-rlc'),
            elsif (UPPER(ext) = '.DWG') then
              imgobj.fileformat := 'OTHER';
              imgobj.import(ctx);
              imgobj.setMimeType('image/vnd.dwg'),
            else
              raise; -- Could not determine mimetype
            end if;
         else
            raise;
         end if;
     END;

    update photos t set t.image=imgobj where rowid =
        thisrowid;

END;

Something like the above could also be done on HTTP data passing the Content-Type from the Request or Response header to set the MIME type.

For audio and video, loading unrecognized data using PL/SQL is much more straightforward. If you know that format is not recognized, you can simply skip the setProperties() step and set what you do know about the media in the object. Setting metadata for audio and video can be an expensive operation that may include scanning the entire file for some formats. So, depending on your loading needs, you may want to set the metadata manually. Here is a similar example of loading an audio and setting the MIME type of the data if we can figure out what it is. A video load would be very similar.

create or replace procedure upload_audio_setmime
     (file_name varchar2,
      prikey_id number,
      descr varchar2,
      loc varchar2)
as
     audobj       ORDSYS.ORDAudio;
     ctx          raw(64):=null;
     thisrowid    urowid;
     ext          varchar2(10);
BEGIN
    insert into sounds t (id, description, location, sound)
          values (prikey_id, descr, loc,

                     ORDSYS.ORDAudio.init())
          returning rowid, t.sound into thisrowid, audobj;

         audobj.importFrom(ctx, 'FILE', 'AUDIODIR', file_name);

      BEGIN

         audobj.setproperties(ctx);

      EXCEPTION
        WHEN OTHERS THEN
           -- Metadata cannot be automatically set. Try and set
           -- mimetype by file extension
           ext := SUBSTR(file_name, INSTR(file_name,'.'));
           if (UPPER(ext) = '.QCP') then
               audobj.setMimeType('audio/EVRC-QCP'),
           elsif (UPPER(ext) = '.AMR') then
               audobj.setMimeType('audio/AMR'),
           else
               raise; -- Could not determine minmetype
           end if;
     END;

     update sounds t set t.sound=audobj where rowid =
         thisrowid;

END;
/

With audio and video, since setProperties() is never called explicitly, we don’t need to identify the exception type.

Another way to handle unrecognized media formats is to use your own media parser. For example, if metadata extraction fails, you may want to set the metadata in the media object using your own parser.

DECLARE
  img ORDImage;
  row_id urowid;
BEGIN

    Select image, rowid into img, row_id from photos where ID
        = 10 for update;
    begin
        img.setProperties();
        EXCEPTION
          WHEN OTHERS THEN
            -- Is this an unsupported format error?
            if (INSTR(sqlerrm, 'IMG-00705') != 0) then
                myMediaPackage.mySetProperties(img);
            else
                raise;
            end if;
    end;

    update photos set image=img where rowid=row_id;
    commit;
END;

In myMediaPackage.mySetProperties(img) you would use the BLOB, and a stored procedure, a stored JAVA procedure, or an external procedure to parse the data and set the appropriate attributes in the image object.

PL/SQL Loading Methods Performance Considerations

When loading media into the database using interMedia PL/SQL methods, the following items should be considered for best performance:

  • Disable logging on LOB columns. Re-execute the procedure to recover a failed data load transaction. This avoids the large amount of binary data being copied into the REDO log file for rolling forward. It is important to realize that this means that you will be responsible for saving the media data, before the next database backup, in the case of database failure (if there is not an alternate database failure recovery mechanism).

  • Load the media data in smaller groups if you run out of resources.

  • Do not use the Oracle cache option for LOB columns. You can turn on caching after the load operation is complete by using the SQL ALTER TABLE MODIFY LOB CACHE statement.

  • Use the INSERT RETURNING clause to obtain empty interMedia objects that were just inserted into the database for data loading later in the procedure.

  • Use ROWIDs to reference rows that are being worked on. The ROWID is obtained in either a SELECT ROWID ... INTO statement or an INSERT RETURNING ROWID ... INTO clause.

  • If you can set the object metadata manually, rather than having the metadata populated with media-processing functions (using the setProperties() method either explicitly or implicitly) you can increase performance.

SQL*Loader

Another option for loading interMedia data into the database is SQL*Loader. The main advantage over PL/SQL and external table loading (covered in the next section) is that using SQL*Loader allows you to load the media over the network. The main disadvantage to SQL*Loader is that object-relational methods, like setProperties(), cannot be invoked with it. These methods can be invoked after the images are loaded if necessary in another procedure.

However, the lack of ability to call methods may not be an issue if it is decided to skip automatic metadata extraction and set the metadata manually. You can use this technique to populate as much known metadata in the media object as you like.

Here is an example of an SQL*Loader control file that loads the raw images into a table, and also sets minimal metadtata, the MIME type, in the image object.

LOAD DATA
INFILE *
INTO TABLE photos
APPEND
FIELDS TERMINATED BY ','
(id,
 description,
 location,
 image column object
      (
        mimetype,
        source column object
        (
          localData_fname FILLER CHAR(12),
          localData LOBFILE(image.source.localData_fname) raw
          terminated by EOF
        )
      )
)

BEGINDATA
3,Goats,Hampshire,image/gif,goats.gif,
4,Flowers,Vermont,image/jpg,flowers.jpg,

To Invoke SQL*Loader, the following command line is used:

sqlldr control=loadimage.ctl log=loadimage.log userid=scott/
tiger@remotedb

As you can see, the ID, the MIME type, and the raw image binary data is loaded in the table. If it is necessary to set further properties of the images, a PL/SQL procedure can be written to scan through the rows and set the image properties, as in the following example.

CREATE OR REPLACE Procedure SetPropsAfterSQLLoader
IS
    total_val number(6);
    cursor c is
      select image, rowid from photos for update;

BEGIN

    total_val := 0;

    FOR row_rec in c
    LOOP
        -- Try not to set properties on images already done
        if (row_rec.image.getWidth() is null) then
           row_rec.image.setProperties();
           update photos t set t.image = row_rec.image
                             where rowid = row_rec.rowid;
        end if;
        END LOOP;
        commit;
   END;
   /
   show errors;

External Tables

Somewhere between PL/SQL and SQL*Loader, is the functionality of database external tables. These tables have the ability to define database tables from flat files stored on the file system. This features uses similar technology to PL/SQL and SQL*Loader.

Note that it is possible to load data using parallel processing that can be tuned with external tables. To load media from external tables, five things are necessary to set up:

  1. A file that holds the table data.

  2. A directory specification.

  3. An external table data file.

  4. A table defined on the data file.

  5. A procedure to copy the data to media objects.

The file that holds the table could contain the following data that looks much like an SQL*Loader table:

10,Goats,Somewhere over the rainbow,goats.gif
11,Flowers,Field in NH,flowers.jpg
:
:
:

As we have seen before, a directory specification must be defined from a user who has the create directory privilege, and use of that directory must be assigned to the user.

SQL> CREATE DIRECTORY LOADMEDIADIR AS 'C:LOADMEDIADIR';
SQL> GRANT READ ON DIRECTORY LOADMEDIADIR TO SCOTT;

Now that the directory definition and data file have been created, a table definition can be defined that will allow the database to see this file as a read-only SQL table:

create table EXTERNAL_MEDIA_TABLE
  (id VARCHAR2(10), Descr VARCHAR2(40), loc VARCHAR2(40),
blobdata BLOB)
     ORGANIZATION EXTERNAL
       (TYPE ORACLE_LOADER DEFAULT DIRECTORY LOADMEDIADIR
        ACCESS PARAMETERS
           (RECORDS DELIMITED BY NEWLINE
             FIELDS terminated by ',' (id CHAR(2),
                         descr CHAR(40),
                         loc CHAR(40), b char(50))
            COLUMN TRANSFORMS (blobdata from LOBFILE(b))
           )
         LOCATION ('tst_ext.dat'))
       PARALLEL;

The table we define does not define a interMedia type because the definition of an object-relational type is not supported with external tables. Of importance here is the COLUMN TRANSFORMS clause. This clause takes the file name specified in the data file and transforms it into a BLOB. At this point we can do some standard SQL operation on the table we have just defined, for example:

SQL> SELECT ID, DESCR, LOC FROM EXTERNAL_MEDIA_TABLE;

At this point, we are ready to move the data to a fully-qualified database media table. This is done with a PL/SQL procedure. This procedure will copy the BLOB data from the external table into an internal table, get the properties of the image, and populate the thumbnail with a scaled down version of the image.

Declare
    cursor c is
      select id, descr, loc, blobdata from
EXTERNAL_MEDIA_TABLE;
    img ORDSYS.ORDIMAGE;
    thmb ORDSYS.ORDIMAGE;
    thisrowid urowid;
begin

  for rec in c
  LOOP
    insert into photos t (id, description, location, image,
                          thumb)
          values (rec.id, rec.descr, rec.loc,
                   ORDSYS.ORDImage.init(),
                   ORDSYS.ORDImage.init())
       returning rowid, t.image, t.thumb into thisrowid, img,
                 thmb;

    img.source.localdata := rec.blobdata;

    img.setproperties();

    img.processCopy('fileFormat=JFIF maxScale=128 128',
                    thmb);

    update photos t set t.image=img, t.thumb=thmb where
           rowid = thisrowid;

    commit;

  END LOOP;
end;
/

drop table EXTERNAL_MEDIA_TABLE;

We use a cursor to select all the records from EXTERNAL_MEDIA_ TABLE. This information is inserted into the database table as well as some initialized media data types. The BLOB data is then copied to the image object, and a setProperties() method extracts metadata from the image. We could catch any exceptions here and handle them by rejecting the image, or perhaps set MIME type based on file extension, but in this case, we are satisfied that the input data is a standard that is understood. The thumbnail is then created and the row updated.

After the data is loaded, the external table can be dropped.

Oracle Data Pump

Data Pump can be used to export media data into a binary file, load this file into another database, or move media data from one database to another over the network. By itself, it cannot do an initial load of multimedia data into the database, but it is worth mentioning here because it is a powerful tool for moving media data from place to place.

Data Pump may be used in various situations where you need to move media data. One such example would be to synchronize media data from a central website to sites around the world so that local customers or users have faster access. Another example may be to distribute the media-processing load. An application that has to load hundreds of thousands of images per hour that require processing, like metadata extraction, format conversion, and scaling, may choose to distribute the load by performing image processing into satellite systems before using Data Pump to move the data to a centralized site.

One way to export media data using Data Pump is to use the expdp utility. This can easily create a Data Pump binary file. For example:

C:>expdp scott/tiger TABLES=photos DUMPFILE=DPDIR:photos.dmp
LOGFILE=DPDIR:photos.log

After the Data Pump file is created, it can be used to import data into another database.

To import the data into another database the impdp command can be used as follows:

C:>impdp scott/tiger TABLES=photos DIRECTORY=DPIMPDIR
DUMPFILE=photos.dmp

You can also use Data Pump to directly transfer information from one database to another. To copy directly from one database to another using Data Pump, a network link must be created in the target database:

SQL> create Database Link remote connect to scott identified
by tiger using 'remotedb';

You can then use impdp on this system to import a table directly from a remote database into a local target database:

C:>impdp scott/tiger TABLES=photos DIRECTORY=dpdir
NETWORK_LINK=remote

Note that the DIRECTORY clause is still necessary if you want a log of the import operation. The log will be created in the directory specified.

If you only want to add rows from a remote database to the local target database into an existing table, the CONTEXT=DATA_ONLY clause is used:

C:>impdp scott/tiger TABLES=photos DIRECTORY=dpdir
NETWORK_LINK=remote CONTENT=DATA_ONLY

Transportable Tablespaces

Database tablespaces are files that are a part of the database. These tablespace files contain the data that are stored in tables, in the case we are interested in, where the media table data is stored.

One feature of the Oracle Database Enterprise Edition is transportable tablespaces. A transportable tablespace allows a system administrator to move a subset of a database from one database and plug it into another database. This can be a table partition, a table, or a set of tables. This can be useful for a number of media applications including:

  • Incremental backups of media database.

  • Copying media data to other media databases.

  • Archival of historical media.

Moving data using transportable tablespaces is quicker than import/ export or Data Pump operations. This is because the tablespace file is simply copied from one system to another. The transportable tablespace metadata is imported into the target database to make it available.

To be transportable, a set of tablespaces to be transported must be self-contained. That is to say that references within the tablespace cannot reference data outside the tablespace set, for example, an index in the tablespace referencing a table outside the tablespace set.

To make use of transportable tables, it is typically necessary to partition the media tables into a number of tablespaces. You may also want to place the binary media data into a tablespace separate from the other table data. You can then transport these tablespaces as a tablespace set.

To create a table that will be used for historical archiving, it can be partitioned so that only a certain date range is placed into the tablespace. When the data is ready to be archived, it can be removed from the database and placed in archive.

Let us assume that we do want to archive pictures after every month. First, we will need a tablespace for each month. Using a SYSDBA account, we create the following tablespaces:

CREATE TABLESPACE augustPhotos DATAFILE 'augustPhotos.dbf'
SIZE 20M;
CREATE TABLESPACE septemberPhotos DATAFILE
'septemberPhotos.dbf' SIZE 20M;

From a user account, we can now create the photos table with the addition of a date to segment the photographs by date.

CREATE TABLE photos
                   (id          NUMBER PRIMARY KEY,
                    description VARCHAR2(40) NOT NULL,
                    location    VARCHAR2(40),
                    created     DATE,
                    image       ORDSYS.ORDIMAGE,
                    thumb       ORDSYS.ORDIMAGE)
    PARTITION BY RANGE (created)
     (partition august VALUES LESS THAN
         (TO_DATE('01-SEP-2005'))
         tablespace augustphotos,
      partition september VALUES LESS THAN
         (TO_DATE('1-OCT-2005'))
          tablespace septemberPhotos);

We can add partitions as needed, for example:

CREATE TABLESPACE octoberPhotos DATAFILE 'octoberPhotos.dbf'
SIZE 20M LOGGING;
ALTER TABLE photos ADD PARTITION october VALUES LESS THAN
(TO_DATE('01-NOV-2005')) tablespace octoberPhotos;

To move the August partition from the photos table, and make the tablespace transportable and self-contained, all outside references must be removed. To do this, we have to exchange the table data into another table and remove the partition from the photos table.

CREATE TABLE photos_august
                   (id          NUMBER PRIMARY KEY,
                    description VARCHAR2(40) NOT NULL,
                    location    VARCHAR2(40),
                    created     DATE,
                    image       ORDSYS.ORDIMAGE,
                    thumb       ORDSYS.ORDIMAGE)
             tablespace augustphotos;


ALTER TABLE photos
   EXCHANGE PARTITION august WITH TABLE photos_august
   WITHOUT VALIDATION;

ALTER TABLE PHOTOS DROP PARTITION august;

From an SYSDBA account, to move this tablespace to another database, we make the tablespace read-only:

ALTER TABLESPACE augustPhotos READ ONLY;

We then use Data Pump to gather the metadata necessary to transport the tablespace from one system to the next.

C:>EXPDP system/welcome1 DUMPFILE=augustPhotos.dmp
DIRECTORY=dpdir TRANSPORT_TABLESPACES='augustPhotos';

At this point, the Data Pump metadata file, augustPhotos.dmp, and tablespace file, augustPhotos.dbf, are copied to the target system using your favorite utility.

On the target system,

C:>IMPDP system/manager1 DUMPFILE=AUGUSTPHOTOS.dmp
DIRECTORY=dpimpdir TRANSPORT_DATAFILES=c:plsql
AUGUSTPHOTOS.DBF

If we want to make the tablespace writeable, we can do this using the alter command on the target and original database from an SYSDBA account:

SQL> ALTER TABLESPACE READ WRITE;

At this time we may want to add this partition to an existing partitioned table in the target database. Let us assume this table is named photos_archive with the same definition as the photos_table. The first thing we need to do is to add a partition to the target table:

SQL> ALTER TABLE photos_archive ADD PARTITION august VALUES
LESS THAN (to_date('01-SEP-2006'));

At this point, we exchange this partition with the table we just added to the database:

SQL> alter table photos_archive exchange partition august
with table photos_august WITHOUT VALIDATION;

Now, we have added the archived photos to the photos_archive table.

HTTP Form Load

In many applications, loading of the data through Web forms is desirable. Media applications are no exception. There are many techniques to create server Web applications to load media data. These are covered in other chapters.

The one thing that is common to all loading of HTTP data is the HTML code necessary to download. For media applications, you must download a file that is local to the client system. A Web form to upload media will require the following code:

  • The enclosing form has the attribute method="post".

  • The enclosing form has the attribute enctype="multipart/form-data".

  • The form has an input form element with the type="file" attribute.

Following is a simple example of a Web form that uploads a file to a Web server.

<form action="http://www.oracle.com/upload_media"
      enctype="multipart/form-data" method="post">
<p>
Input file name:<br>
<input type="file" name="mediafile" size="40">
</p>
<p>
<input type="submit" value="Upload">
</p>
</form>

You can have as many file input fields as you like to upload more than one media file at a time.

The most important advantage of using a Web form as an interface is the fact that Web browsers are ubiquitous. There is no need to ship an application out to clients.

Thick Client Loading

Another way to load media data into the database is to use a thick client. If you have ever dealt with having to upload digital images to a site to order prints, you will have noticed that many allow upload of images from either a Web browser or their custom written application that you can download from their site. They created the thick client to make their service more usable and friendly.

A thick client can have many advantages including:

  • A more user-friendly interface that includes drag, drop, cut, and paste so that you can easily select a number of files to be uploaded in a batch.

  • Since you have control of the upload data stream, it is possible to create an application that will restart failed batch uploads at the point of failure.

  • Better feedback to the user on upload status, how much time is left, percent done, etc.

Examples of loading data with a thick client have been given in the introduction to interMedia’s API section.

Summary

There are numerous ways to load media data and to move media data from one database to another. This chapter has outlined a number of these techniques.

Which method that is chosen will depend highly on the type of data, the volume of data, and where the data is coming from. For example, if the data is coming from users, it is probably best to use a Web form so that they can insert the media directly into the database and analyze the media. If the data is coming from a high-speed scanner, it may be best to load the data from the scanner result files and skip the somewhat expensive step of extracting metadata from the media by analyzing the media since most of this metadata is known beforehand.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset