@unitybase/blob-stores

BLOB stores (attributes of type Document on ORM level)

Entity attribute of Document type with storeName property for this attribute should be defined. Content (data stored in database) of such attributes is a meta-information about file - a serialized BlobStoreItem object, not an actual file content.

In case entity is stored in the database using {mStorage} mixin, DDL generator create nvarchar(2000) field in database and store there {BlobStoreItem} serialized to JSON.

For Virtual entity developer should implement select method and fill BlobStoreItem manually (for example by parsing file content as done in ubm_form).

In the store definition section of application config developer describe stores. Each store must implement interface described below.

The store class itself provide storing and retrieving file content (based on meta-information stored in the entity attribute).

From client-side POV uploading files to server is separated onto two part. Like in gmail when you send mail with attachment you can attach file, and gmail send it to server, but you do not send mail itself yet - this is first stage. Result of this stage is information about where file on server stored. When you send email client pass to server email attributes, body and information about attached files. This is the same UnityBase do in the second stage.

Server side usage:

// get dirty (not committed yet) content of my_entity.docAttribute with ID = 12312 as ArrayBuffer
let tmpContent = App.blobStores.getContent(
   {ID: 12312, entity: 'my_entity', attribute: 'blobAttribute', isDirty: true},
   {encoding: 'bin'}
)

// get BLOB content of my_entity.docAttribute with ID = 12312 as base64 string
let base64Content = App.blobStores.getContent(
  {ID: 12312, entity: 'my_entity', attribute: 'blobAttribute'},
  {encoding: 'base64'}
)

// get BLOB content of my_entity.docAttribute with ID = 12312 as string
let base64Content = App.blobStores.getContent(
  {ID: 12312, entity: 'my_entity', attribute: 'blobAttribute'},
  {encoding: 'utf8'}
)

// read file and but it to BLOB store (not committed yet)
let content = fs.readFileSync(__filename, {encoding: 'bin'})
let fn = path.basename(__filename)
let blobItem = App.blobStores.putContent(
  {ID: 12312, entity: 'my_entity', attribute: 'blobAttribute'},
  content
)

// commit blob store
let dataStore = UB.DataStore(my_entity)
dataStore.run('update', {
  execParams: {
    ID: 12312,
    blobAttribute: JSON.stringify(blobItem)
  }
})

Upload file to server

So in UnityBase upload file to to the server is performed in two stages:

  1. Upload file to temporary store - on this stage client call setDocument app level method and pass file content to server with additional parameter isDirty=true, server store file in the temporary place.

  2. Client execute insert or update entity method and pass (with other attributes) string, returned on the first stage as a value of Document type attribute. On this stage server see what user want to update/insert Document and, based on Domain information, know what type of store is used for this attribute. Server:

  3. Finally UnityBase update entity and commit database transaction (in case entity is non-virtual)

Download file from server

For download file from server client call getDocument endpoint

Methods

getContent(request, optionsopt)String|Buffer|ArrayBuffer|null inner

Server-side method for obtaining BLOB content from the blob store. Return null in case attribute value is null.
Arguments:
  1. request (BlobStoreRequest)
  2. [options] (Object)
    Properties
    1. [encoding] (String|Null)  Possible values: 'bin' 'ascii' 'base64' 'binary' 'hex' ucs2/ucs-2/utf16le/utf-16le utf8/utf-8 if null will return Buffer, if bin - ArrayBuffer

markRevisionAsPermanent(request) inner

For a historical BLOB stores mark specified revision as a permanent. Permanents revisions will not be deleted during history rotation.
Arguments:
  1. request (BlobStoreRequest)
    Properties
    1. revision (Number)  revision to be marked as permanent
Example
const UB = require(@unitybase/ub')
const App = UB.App
App.blobStores.markRevisionAsPermanent({
  entity: 'my_entity',
  attribute: 'attributeOfTypeDocument',
  ID: 1000,
  revision: 2
})

putContent(request, content)BlobStoreItem inner

Server-side method for putting BLOB content to BLOB store temporary storage
Arguments:
  1. request (BlobStoreRequest)
  2. content (ArrayBuffer|String)
Example
// convert base64 encoded string stored in `prm.signature` to binary and put to the store
 docContent = App.blobStores.putContent({
   entity: 'iit_signature',
   attribute: 'signature',
   ID: ID,
   fileName: ID + '.p7s'
 }, Buffer.from(prm.signature, 'base64'))

Type Definitions

BlobStoreItem

Blob store item content (JSON stored in database)
Properties:
Name Type Attributes Description
v Number <optional>

Store version. Empty for UB<5. Store implementation must check v for backward compatibility

store String

Code of store implementation from application config. If empty - use a store from attribute configuration

fName String

File name inside store (auto generated in most case)

origName String

Original file name (as user upload it)

relPath String <optional>

Relative path of fName inside store folder (for file-based stores)

ct String

Content type

size Number

Content size

md5 String

Content MD5 checksum

revision Number <optional>

Content revision. Used only for stores with historyDepth > 0

deleting Boolean <optional>

If true content must be deleted/archived during commit

isDirty Boolean <optional>

????

isPermanent Boolean <optional>

If true - do not delete content during history rotation

BlobStoreRequest

Blob store request (parameters passed to get|setDocument)
Properties:
Name Type Attributes Description
ID Number
entity String
attribute String
isDirty Boolean <optional>
fileName String <optional>
revision Number <optional>
extra String <optional>

Store-specific extra parameters