Skip to main content

Storage

Currently supported storage capabilities include: Entity Storage.

Requirements

ONES@ones-op/sdk@ones/cli
v6.31.0v1.0.8v1.40.10

Entity Storage

Entities are user-defined data structures used to store application data.

ONES entity storage SDK allows you to query the data stored in these structures using various query conditions, or perform data management operations such as creating, updating, and deleting data.

Entity data type

Entities have multiple typed properties. You can define properties using the following data types:

  • boolean
  • integer
  • float
  • string
  • text

Entity data specification

Data typeWhether indexing is supportedWhether length needs to be definedSpecification of the data to be written
booleanSupportedNotrue | false
integerSupportedNo(-9223372036854775808, 9223372036854775807]
floatSupportedNo(-1.7976931348623157e308, -2.2250738585072014e−308)
0
(2.2250738585072014e−308, 1.7976931348623157e308)
Supports up to 15 digits of precision
stringSupportedYes
The defined range is [1, 2048]
The length of all string type attributes is defined by the user.
The total length of all string type attributes does not exceed 2048 bytes.
textUnsupportedNoEach attribute can be written to a maximum of 32768 bytes

Different between string and text

string:String type for indexing data, meanwhile string type should define specific length.

text:Text type for storing business data.

Entity definition

Entity definition needs to be declared in the config/plugin.yaml file.

Basic entity definition

The basic entity definition, the structure of the declaration is as follows:

  • name, required, entity name.
  • attributes, required, custom attribute definition.
  • indexes, optional, custom index definition.
config/plugin.yaml
storage:
entities:
- name: <entity1>
attributes:
<attribute1>:
type: <type>
required: true
<attribute2>:
type: <type>
default: <value>
# ... more attributes
<attributeN>:
type: <type>
default: <value>
indexes:
- name: <index1>
range_attribute: <attribute name>
# ... more indexes
- name: <indexN>
range_attribute: <attribute name>
partition:
- <attribute name>
# ... more attributes
- <attribute name>
- name: <entity2>
# ... more entity
- name: <entityN>

Custom attribute definition

Custom attributes support the following two declaration structures:

  • Required attributes
    • type, required, custom attribute type, need to declare supported data types.
      • If you define the attribute type string, you need to additionally define the length, required, the defined range is [1, 2048].
    • When creating or updating entity data, the required attribute value must conform to the data type of the current field.
    • Declare required attributes, and do not declare default values.
  • Declare the attribute with the default value
    • type, required, the type of the custom attribute, you need to declare the supported data type.
      • If you define the attribute type string, you need to additionally define the length, required, the defined range is [1, 2048].
    • When creating entity data, if it is missing, the entity data will be created with the default value.
    • When updating entity data, if it is missing, the original attribute value will be kept unchanged.
    • The declaration of the default value must comply with the data type of the current field.
    • The attribute that declares the default value cannot be declared as required.
config/plugin.yaml
# case1
<attribute1>:
type: <type>
required: true
# case2
<attribute2>:
type: <type>
default: <value>
# case3
<attribute1>:
type: string
length: 32
required: true
# case4
<attribute2>:
type: string
length: 32
default: <value>

Custom index definition

The structure of the basic declaration of a custom index is as follows:

  • Custom index definition
    • name, required, index name.
    • range_attribute, required, the attribute to be queried when using conditional query.
      • The attribute name declared in attributes needs to be filled in, and the type is one of: boolean, integer, float, string.
    • partition, optional, when using index query, query by partition attribute value. And sort by current attribute.
      • The attribute name declared in attributes needs to be filled in, and the type is one of: boolean, integer, float, string.
    • unique, optional, the uniqueness mark of data. When creating or updating data, the data needs to be unique.
      • The combination of attribute names filled in according to range_attribute and partition needs to be unique.
    • For specific examples, please refer to: Set entity query where condition.
config/plugin.yaml
# case1
- name: <index1>
range_attribute: <attribute name>
# case2
- name: <index2>
range_attribute: <attribute name>
partition:
- <attribute name>
- <attribute name>
# case3
- name: <index1>
range_attribute: <attribute name>
unique: true
# case4
- name: <index2>
range_attribute: <attribute name>
unique: true
partition:
- <attribute name>
- <attribute name>

Entity definition example

config/plugin.yaml
storage:
entities:
- name: employee
attributes:
name:
type: string
length: 32
required: true
age:
type: integer
required: true
deleted:
type: boolean
required: true
indexes:
- name: find_by_name
range_attribute: name
- name: find_by_age_in_deleted_partition
range_attribute: age
partition:
- deleted

Entity definition specification

TypeSpecification
EntityThe maximum number of entity declarations is 64
The maximum length of entity name is 32 bytes
And it meets the regular expression /^[_a-z0-9]32$/
AttributesThe maximum number of entity attribute declarations is 32
The maximum length of entity attribute name is 64 bytes
And it meets the regular expression /^[_a-z0-9]64$/
IndexesThe maximum number of custom index declarations is 64
The maximum length of custom index name is 64 bytes
And it meets the regular expression /^[_a-z0-9]64$/

Entity management

Entity management, including creating entities and updating entities.

Entity management actions will be executed during the life cycle of the plugin.

And they are verified according to the declaration specification of the entity definition.

LifecycleEntity management
Install the plugin for the first timeCreate entities according to entity definitions.
Upgrade pluginsCompare the differences in entity definitions and add attributes and indexes.
Existing attributes and indexes cannot be modified or deleted.
Uninstall pluginsEntity data is retained and data export is supported.
Uninstall the plugin and then reinstall itCreate new entities.

Notes on plugin upgrades

Plugins can be upgraded differentially between different versions.

Therefore, during the iteration of a plugin, entity definitions can only add attributes and indexes.

When querying data, if the entity data is historical data, its newly added attributes are returned null by default.

backend/src/index.ts
import { storage } from '@ones-op/sdk/backend'

const { entity } = storage

entity('employee')
.query()
.getOne()
.then((data) => {
// department is new attribute and return null
console.log(data?.value.department)
})

Generally, plugins are recommended for data migration or adding new business logic. That is:

backend/src/index.ts
import { storage } from '@ones-op/sdk/backend'

const { entity } = storage

// data migration
entity('employee')
.query()
.getMany()
.then((data) => {
entity('employee').batchSet(
data.data.map((item) => {
item.value.department = item.value.department || 'development'
return item
}),
)
})

// adding new business logic
const getDepartment = (key: string) => {
return entity('employee')
.get(key)
.then((data) => {
return data?.department || 'development'
})
}

Entity data management

In each entity, a key is included by default, and the key is unique.

When performing Entity data management, you need to use the key to perform data management operations such as creating, updating, and deleting data.

Please refer to: Entity Storage SDK.

Entity key specification

TypeSpecification
KeyMaximum length is 64 bytes
and satisfies the regular expression /^[_a-z0-9]{1,64}$/