org.h2.store

## Class LobStorageBackend

- java.lang.Object
- - org.h2.store.LobStorageBackend

All Implemented Interfaces:
  LobStorageInterface

    public class LobStorageBackend
    extends java.lang.Object
    implements LobStorageInterface

This class stores LOB objects in the database, in tables. This is the back-end i.e. the server side of the LOB storage.

Using the system session

Why do we use the system session to store the data? Some LOB operations can take a very long time. If we did them on a normal session, we would be locking the LOB tables for long periods of time, which is extremely detrimental to the rest of the system. Perhaps when we shift to the MVStore engine, we can revisit this design decision (using the StreamStore, that is, no connection at all).

Locking

Normally, the locking order in H2 is: first lock the Session object, then lock the Database object. However, in the case of the LOB data, we are using the system session to store the data. If we locked the normal way, we see deadlocks caused by the following pattern:

      Thread 1:
         locks normal session
         locks database
         waiting to lock system session
      Thread 2:
          locks system session
          waiting to lock database.

So, in this class alone, we do two things: we have our very own dedicated session, the LOB session, and we take the locks in this order: first the Database object, and then the LOB session. Since we own the LOB session, no-one else can lock on it, and we are safe.

### Nested Class Summary

Nested Classes
`class` `LobStorageBackend.LobInputStream` An input stream that reads from a LOB.

### Field Summary

Fields
`static java.lang.String` `LOB_DATA_TABLE` The name of the lob data table.

### Constructor Summary

Constructors
Constructor and Description
`LobStorageBackend(Database database)`

### Method Summary

Methods
`ValueLobDb` `copyLob(ValueLobDb old, int tableId, long length)` Copy a lob.
`Value` `createBlob(java.io.InputStream in, long maxLength)` Create a BLOB object.
`Value` `createClob(java.io.Reader reader, long maxLength)` Create a CLOB object.
`java.io.InputStream` `getInputStream(ValueLobDb lob, byte[] hmac, long byteCount)` Get the input stream for the given lob.
`void` `init()` Initialize the lob storage.
`boolean` `isReadOnly()` Whether the storage is read-only
`void` `removeAllForTable(int tableId)` Remove all LOBs for this table.
`void` `removeLob(ValueLobDb lob)` Delete a LOB (from the database, if it is stored there).
`void` `setTable(ValueLobDb lob, int table)` Set the table reference of this lob.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Field Detail

#### LOB_DATA_TABLE

    public static final java.lang.String LOB_DATA_TABLE

The name of the lob data table. If this table exists, then lob storage is used.

See Also:
  Constant Field Values

### Constructor Detail

#### LobStorageBackend

    public LobStorageBackend(Database database)

### Method Detail

#### init

    public void init()

Description copied from interface: `LobStorageInterface`
Initialize the lob storage.

Specified by:
  `init` in interface `LobStorageInterface`

#### removeAllForTable

    public void removeAllForTable(int tableId)

Description copied from interface: `LobStorageInterface`
Remove all LOBs for this table.

Specified by:
  `removeAllForTable` in interface `LobStorageInterface`
Parameters:
  `tableId` - the table id

#### removeLob

    public void removeLob(ValueLobDb lob)

Description copied from interface: `LobStorageInterface`
Delete a LOB (from the database, if it is stored there).

Specified by:
  `removeLob` in interface `LobStorageInterface`
Parameters:
  `lob` - the lob

#### getInputStream

    public java.io.InputStream getInputStream(ValueLobDb lob,
                                     byte[] hmac,
                                     long byteCount)
                                       throws java.io.IOException

Description copied from interface: `LobStorageInterface`
Get the input stream for the given lob.

Specified by:
  `getInputStream` in interface `LobStorageInterface`
Parameters:
  `lob` - the lob id
  `hmac` - the message authentication code (for remote input streams)
  `byteCount` - the number of bytes to read, or -1 if not known
Returns:
  the stream
Throws:
  `java.io.IOException`

#### isReadOnly

    public boolean isReadOnly()

Description copied from interface: `LobStorageInterface`
Whether the storage is read-only

Specified by:
  `isReadOnly` in interface `LobStorageInterface`
Returns:
  true if yes

#### copyLob

    public ValueLobDb copyLob(ValueLobDb old,
                     int tableId,
                     long length)

Description copied from interface: `LobStorageInterface`
Copy a lob.

Specified by:
  `copyLob` in interface `LobStorageInterface`
Parameters:
  `old` - the old lob
  `tableId` - the new table id
  `length` - the length
Returns:
  the new lob

#### createBlob

    public Value createBlob(java.io.InputStream in,
                   long maxLength)

Description copied from interface: `LobStorageInterface`
Create a BLOB object.

Specified by:
  `createBlob` in interface `LobStorageInterface`
Parameters:
  `in` - the input stream
  `maxLength` - the maximum length (-1 if not known)
Returns:
  the LOB

#### createClob

    public Value createClob(java.io.Reader reader,
                   long maxLength)

Description copied from interface: `LobStorageInterface`
Create a CLOB object.

Specified by:
  `createClob` in interface `LobStorageInterface`
Parameters:
  `reader` - the reader
  `maxLength` - the maximum length (-1 if not known)
Returns:
  the LOB

#### setTable

    public void setTable(ValueLobDb lob,
                int table)

Description copied from interface: `LobStorageInterface`
Set the table reference of this lob.

Specified by:
  `setTable` in interface `LobStorageInterface`
Parameters:
  `lob` - the lob
  `table` - the table