diff --git a/packages/store/src/StoreData.sol b/packages/store/src/StoreData.sol index b5b99f0616..d1df66566f 100644 --- a/packages/store/src/StoreData.sol +++ b/packages/store/src/StoreData.sol @@ -6,12 +6,26 @@ import { IStoreData } from "./IStoreData.sol"; import { StoreRead } from "./StoreRead.sol"; import { StoreCore } from "./StoreCore.sol"; +/** + * @title Store Data Contract + * @notice This contract integrates the core storage functionalities and provides an interface for data storage. + * @dev This abstract contract initializes `StoreCore`, implements `storeVersion`, and read methods, + * but not write methods. + */ abstract contract StoreData is IStoreData, StoreRead { + /** + * @notice Constructs the StoreData contract and initializes the StoreCore. + * @dev Emits a HelloStore event upon creation. + */ constructor() { StoreCore.initialize(); emit HelloStore(STORE_VERSION); } + /** + * @notice Retrieves the version of the store. + * @return The current version of the store as a bytes32. + */ function storeVersion() public pure returns (bytes32) { return STORE_VERSION; } diff --git a/packages/store/src/StoreHook.sol b/packages/store/src/StoreHook.sol index 25dc9c3eb3..4a927c039e 100644 --- a/packages/store/src/StoreHook.sol +++ b/packages/store/src/StoreHook.sol @@ -7,71 +7,174 @@ import { PackedCounter } from "./PackedCounter.sol"; import { FieldLayout } from "./FieldLayout.sol"; import { ResourceId } from "./ResourceId.sol"; +/** + * @title Store Hook Contract + * @notice This abstract contract provides hooks for the storage operations. + * @dev Implementers should override the hook functions to provide custom logic. + * If any hooks are activated without overriding these functions, they revert. + */ abstract contract StoreHook is IStoreHook { - // ERC-165 supportsInterface (see https://eips.ethereum.org/EIPS/eip-165) + /** + * @notice Check if the interface is supported. + * @dev This function is a part of the ERC-165 standard. + * @param interfaceId The ID of the interface to check. + * @return true if the interface is supported, false otherwise. + */ function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { return interfaceId == STORE_HOOK_INTERFACE_ID || interfaceId == ERC165_INTERFACE_ID; } + /** + * @notice Hook that runs before setting a record. + * @dev This function should be overridden to provide custom logic. + * @param tableId The ID of the table where the record is to be set. + * @param keyTuple An array representing the composite key for the record. + * @param staticData The static data of the record. + * @param encodedLengths The encoded lengths of the dynamic data of the record. + * @param dynamicData The dynamic data of the record. + * @param fieldLayout The layout of the field, see FieldLayout.sol. + */ function onBeforeSetRecord( - ResourceId, - bytes32[] memory, - bytes memory, - PackedCounter, - bytes memory, - FieldLayout + ResourceId tableId, + bytes32[] memory keyTuple, + bytes memory staticData, + PackedCounter encodedLengths, + bytes memory dynamicData, + FieldLayout fieldLayout ) public virtual { revert StoreHook_NotImplemented(); } + /** + * @notice Hook that runs after setting a record. + * @dev This function should be overridden to provide custom logic. + * @param tableId The ID of the table where the record was set. + * @param keyTuple An array representing the composite key for the record. + * @param staticData The static data of the record. + * @param encodedLengths The encoded lengths of the dynamic data of the record. + * @param dynamicData The dynamic data of the record. + * @param fieldLayout The layout of the field, see FieldLayout.sol. + */ function onAfterSetRecord( - ResourceId, - bytes32[] memory, - bytes memory, - PackedCounter, - bytes memory, - FieldLayout + ResourceId tableId, + bytes32[] memory keyTuple, + bytes memory staticData, + PackedCounter encodedLengths, + bytes memory dynamicData, + FieldLayout fieldLayout ) public virtual { revert StoreHook_NotImplemented(); } - function onBeforeSpliceStaticData(ResourceId, bytes32[] memory, uint48, bytes memory) public virtual { + /** + * @notice Hook that runs before splicing static (fixed length) data. + * @dev This function should be overridden to provide custom logic. + * Splice operations in static data always overwrite data starting at + * the start position, + * so the total length of the data remains the same and no data is shifted. + * @param tableId The ID of the table where the data is to be spliced. + * @param keyTuple An array representing the composite key for the record. + * @param start The start byte position for splicing. + * @param data The data to be written to the static data of the record at the start byte. + */ + function onBeforeSpliceStaticData( + ResourceId tableId, + bytes32[] memory keyTuple, + uint48 start, + bytes memory data + ) public virtual { revert StoreHook_NotImplemented(); } - function onAfterSpliceStaticData(ResourceId, bytes32[] memory, uint48, bytes memory) public virtual { + /** + * @notice Hook that runs after splicing static (fixed length) data. + * @dev This function should be overridden to provide custom logic. + * Splice operations in static data always overwrite data starting at + * the start position, + * so the total length of the data remains the same and no data is shifted. + * @param tableId The ID of the table where the data is to be spliced. + * @param keyTuple An array representing the composite key for the record. + * @param start The start byte position for splicing. + * @param data The data to be written to the static data of the record at the start byte. + */ + function onAfterSpliceStaticData( + ResourceId tableId, + bytes32[] memory keyTuple, + uint48 start, + bytes memory data + ) public virtual { revert StoreHook_NotImplemented(); } + /** + * @notice Hook that runs before splicing dynamic (variable length) data. + * @dev This function should be overridden to provide custom logic. + * Splice operations in dynamic data always reach the end of the dynamic data + * to avoid shifting data after the inserted or deleted data. + * @param tableId The ID of the table where the data is to be spliced. + * @param keyTuple An array representing the composite key for the record. + * @param dynamicFieldIndex The index of the dynamic field. + * @param startWithinField The start byte position within the field for splicing. + * @param deleteCount The number of bytes to delete in the dynamic data of the record. + * @param encodedLengths The encoded lengths of the dynamic data of the record. + * @param data The data to be inserted into the dynamic data of the record at the start byte. + */ function onBeforeSpliceDynamicData( - ResourceId, - bytes32[] memory, - uint8, - uint40, - uint40, - PackedCounter, - bytes memory + ResourceId tableId, + bytes32[] memory keyTuple, + uint8 dynamicFieldIndex, + uint40 startWithinField, + uint40 deleteCount, + PackedCounter encodedLengths, + bytes memory data ) public virtual { revert StoreHook_NotImplemented(); } + /** + * @notice Hook that runs after splicing dynamic (variable length) data. + * @dev This function should be overridden to provide custom logic. + * Splice operations in dynamic data always reach the end of the dynamic data + * to avoid shifting data after the inserted or deleted data. + * @param tableId The ID of the table where the data is to be spliced. + * @param keyTuple An array representing the composite key for the record. + * @param dynamicFieldIndex The index of the dynamic field. + * @param startWithinField The start byte position within the field for splicing. + * @param deleteCount The number of bytes to delete in the dynamic data of the record. + * @param encodedLengths The encoded lengths of the dynamic data of the record. + * @param data The data to be inserted into the dynamic data of the record at the start byte. + */ function onAfterSpliceDynamicData( - ResourceId, - bytes32[] memory, - uint8, - uint40, - uint40, - PackedCounter, - bytes memory + ResourceId tableId, + bytes32[] memory keyTuple, + uint8 dynamicFieldIndex, + uint40 startWithinField, + uint40 deleteCount, + PackedCounter encodedLengths, + bytes memory data ) public virtual { revert StoreHook_NotImplemented(); } - function onBeforeDeleteRecord(ResourceId, bytes32[] memory, FieldLayout) public virtual { + /** + * @notice Hook that runs before deleting a record. + * @dev This function should be overridden to provide custom logic. + * @param tableId The ID of the table where the record is to be deleted. + * @param keyTuple An array representing the composite key for the record. + * @param fieldLayout The layout of the field, see FieldLayout.sol. + */ + function onBeforeDeleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public virtual { revert StoreHook_NotImplemented(); } - function onAfterDeleteRecord(ResourceId, bytes32[] memory, FieldLayout) public virtual { + /** + * @notice Hook that runs after deleting a record. + * @dev This function should be overridden to provide custom logic. + * @param tableId The ID of the table where the record is to be deleted. + * @param keyTuple An array representing the composite key for the record. + * @param fieldLayout The layout of the field, see FieldLayout.sol. + */ + function onAfterDeleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public virtual { revert StoreHook_NotImplemented(); } } diff --git a/packages/store/src/StoreRead.sol b/packages/store/src/StoreRead.sol index f64d66b803..b63bbddf9a 100644 --- a/packages/store/src/StoreRead.sol +++ b/packages/store/src/StoreRead.sol @@ -9,19 +9,46 @@ import { Schema } from "./Schema.sol"; import { PackedCounter } from "./PackedCounter.sol"; import { ResourceId } from "./ResourceId.sol"; +/** + * @title StoreRead + * @dev A contract that provides read operations for storage tables using `StoreCore`. + */ contract StoreRead is IStoreRead { + /** + * @notice Fetches the field layout for a given table. + * @param tableId The ID of the table for which to retrieve the field layout. + * @return fieldLayout The layout of fields in the specified table. + */ function getFieldLayout(ResourceId tableId) public view virtual returns (FieldLayout fieldLayout) { fieldLayout = StoreCore.getFieldLayout(tableId); } + /** + * @notice Retrieves the value schema for a given table. + * @param tableId The ID of the table. + * @return valueSchema The schema for values in the specified table. + */ function getValueSchema(ResourceId tableId) public view virtual returns (Schema valueSchema) { valueSchema = StoreCore.getValueSchema(tableId); } + /** + * @notice Retrieves the key schema for a given table. + * @param tableId The ID of the table. + * @return keySchema The schema for keys in the specified table. + */ function getKeySchema(ResourceId tableId) public view virtual returns (Schema keySchema) { keySchema = StoreCore.getKeySchema(tableId); } + /** + * @notice Fetches a record from a specified table using a provided key tuple. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key to fetch the record. + * @return staticData The static data of the record. + * @return encodedLengths Encoded lengths of dynamic data. + * @return dynamicData The dynamic data of the record. + */ function getRecord( ResourceId tableId, bytes32[] calldata keyTuple @@ -29,6 +56,15 @@ contract StoreRead is IStoreRead { return StoreCore.getRecord(tableId, keyTuple); } + /** + * @notice Fetches a record from a specified table using a provided key tuple and field layout. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key to fetch the record. + * @param fieldLayout The layout of fields to retrieve. + * @return staticData The static data of the record. + * @return encodedLengths Encoded lengths of dynamic data. + * @return dynamicData The dynamic data of the record. + */ function getRecord( ResourceId tableId, bytes32[] calldata keyTuple, @@ -37,6 +73,15 @@ contract StoreRead is IStoreRead { return StoreCore.getRecord(tableId, keyTuple, fieldLayout); } + /** + * @notice Retrieves data for a specified field in a record. + * @dev This overload loads the FieldLayout from storage. If the table's FieldLayout is known + * to the caller, it should be passed in to the other overload to avoid the storage read. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key to fetch the field. + * @param fieldIndex Index of the field to retrieve. + * @return data The data of the specified field. + */ function getField( ResourceId tableId, bytes32[] calldata keyTuple, @@ -45,6 +90,14 @@ contract StoreRead is IStoreRead { data = StoreCore.getField(tableId, keyTuple, fieldIndex); } + /** + * @notice Retrieves data for a specified field in a record. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key to fetch the field. + * @param fieldIndex Index of the field to retrieve. + * @param fieldLayout The layout of fields for the retrieval. + * @return data The data of the specified field. + */ function getField( ResourceId tableId, bytes32[] calldata keyTuple, @@ -54,6 +107,14 @@ contract StoreRead is IStoreRead { data = StoreCore.getField(tableId, keyTuple, fieldIndex, fieldLayout); } + /** + * @notice Retrieves data for a specific static (fixed length) field in a record. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key to fetch the static field. + * @param fieldIndex Index of the static field to retrieve. + * @param fieldLayout The layout of fields for the retrieval. + * @return data The static data of the specified field. + */ function getStaticField( ResourceId tableId, bytes32[] calldata keyTuple, @@ -63,6 +124,13 @@ contract StoreRead is IStoreRead { data = StoreCore.getStaticField(tableId, keyTuple, fieldIndex, fieldLayout); } + /** + * @notice Retrieves data for a specific dynamic (variable length) field in a record. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key to fetch the dynamic field. + * @param dynamicFieldIndex Index of the dynamic field to retrieve. + * @return data The dynamic data of the specified field. + */ function getDynamicField( ResourceId tableId, bytes32[] calldata keyTuple, @@ -71,6 +139,15 @@ contract StoreRead is IStoreRead { data = StoreCore.getDynamicField(tableId, keyTuple, dynamicFieldIndex); } + /** + * @notice Calculates the length of a specified field in a record. + * @dev This overload loads the FieldLayout from storage. If the table's FieldLayout is known + * to the caller, it should be passed in to the other overload to avoid the storage read. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key. + * @param fieldIndex Index of the field to measure. + * @return The length of the specified field. + */ function getFieldLength( ResourceId tableId, bytes32[] memory keyTuple, @@ -79,6 +156,14 @@ contract StoreRead is IStoreRead { return StoreCore.getFieldLength(tableId, keyTuple, fieldIndex); } + /** + * @notice Calculates the length of a specified field in a record. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key. + * @param fieldIndex Index of the field to measure. + * @param fieldLayout The layout of fields for measurement. + * @return The length of the specified field. + */ function getFieldLength( ResourceId tableId, bytes32[] memory keyTuple, @@ -88,6 +173,13 @@ contract StoreRead is IStoreRead { return StoreCore.getFieldLength(tableId, keyTuple, fieldIndex, fieldLayout); } + /** + * @notice Calculates the length of a specified dynamic (variable length) field in a record. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key. + * @param dynamicFieldIndex Index of the dynamic field to measure. + * @return The length of the specified dynamic field. + */ function getDynamicFieldLength( ResourceId tableId, bytes32[] memory keyTuple, @@ -96,6 +188,16 @@ contract StoreRead is IStoreRead { return StoreCore.getFieldLength(tableId, keyTuple, dynamicFieldIndex); } + /** + * @notice Retrieves a slice of a dynamic (variable length) field. + * @param tableId The ID of the table. + * @param keyTuple The tuple used as a key to fetch the dynamic field slice. + * @param dynamicFieldIndex Index of the dynamic field to slice. + * @param start The starting position of the slice. + * @param end The ending position of the slice. + * @return The sliced data from the specified dynamic field. + */ + function getDynamicFieldSlice( ResourceId tableId, bytes32[] memory keyTuple, diff --git a/packages/store/src/StoreSwitch.sol b/packages/store/src/StoreSwitch.sol index 08af0e37b5..dd099d3ab5 100644 --- a/packages/store/src/StoreSwitch.sol +++ b/packages/store/src/StoreSwitch.sol @@ -11,15 +11,28 @@ import { PackedCounter } from "./PackedCounter.sol"; import { ResourceId } from "./ResourceId.sol"; /** - * Call IStore functions on self or msg.sender, depending on whether the call is a delegatecall or regular call. + * @title StoreSwitch Library + * @notice This library serves as an interface switch to interact with the store, + * either by directing calls to itself or to a designated external store. + * @dev The primary purpose is to abstract the storage details, such that the + * calling function doesn't need to know if it's interacting with its own + * storage or with an external contract's storage. */ library StoreSwitch { + /// @dev Internal constant representing the storage slot used by the library. bytes32 private constant STORAGE_SLOT = keccak256("mud.store.storage.StoreSwitch"); + /** + * @dev Represents the layout of the storage slot (currently just the address) + */ struct StorageSlotLayout { - address storeAddress; + address storeAddress; // Address of the external store (or self). } + /** + * @notice Gets the storage layout. + * @return layout The current storage layout. + */ function _layout() private pure returns (StorageSlotLayout storage layout) { bytes32 slot = STORAGE_SLOT; assembly { @@ -28,9 +41,10 @@ library StoreSwitch { } /** - * Get the Store address for use by other StoreSwitch functions. - * 0x00 is a magic number for msg.sender - * (which means that uninitialized storeAddress is msg.sender by default) + * @notice Fetch the store address to be used for data operations. + * If _storeAddress is zero, it means that it's uninitialized and + * therefore it's the default (msg.sender). + * @return Address of the store, or `msg.sender` if uninitialized. */ function getStoreAddress() internal view returns (address) { address _storeAddress = _layout().storeAddress; @@ -42,13 +56,20 @@ library StoreSwitch { } /** - * Set the Store address for use by other StoreSwitch functions. - * If it stays uninitialized, StoreSwitch falls back to calling store methods on msg.sender. + * @notice Set the store address for subsequent operations. + * @dev If it stays uninitialized, StoreSwitch falls back to calling store methods on msg.sender. + * @param _storeAddress The address of the external store contract. */ function setStoreAddress(address _storeAddress) internal { _layout().storeAddress = _storeAddress; } + /** + * @notice Register a store hook for a particular table. + * @param tableId Unique identifier of the table. + * @param hookAddress Address of the hook contract. + * @param enabledHooksBitmap Bitmap representing the hooks which this contract overrides. + */ function registerStoreHook(ResourceId tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { @@ -58,6 +79,11 @@ library StoreSwitch { } } + /** + * @notice Unregister a previously registered store hook. + * @param tableId Unique identifier of the table. + * @param hookAddress Address of the hook contract to be unregistered. + */ function unregisterStoreHook(ResourceId tableId, IStoreHook hookAddress) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { @@ -67,6 +93,11 @@ library StoreSwitch { } } + /** + * @dev Fetches the field layout for a specified table. + * @param tableId The ID of the table for which to retrieve the field layout. + * @return fieldLayout The layout of the fields in the specified table. + */ function getFieldLayout(ResourceId tableId) internal view returns (FieldLayout fieldLayout) { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { @@ -76,6 +107,11 @@ library StoreSwitch { } } + /** + * @dev Retrieves the value schema for a specified table. + * @param tableId The ID of the table for which to retrieve the value schema. + * @return valueSchema The schema for values in the specified table. + */ function getValueSchema(ResourceId tableId) internal view returns (Schema valueSchema) { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { @@ -85,6 +121,11 @@ library StoreSwitch { } } + /** + * @dev Retrieves the key schema for a specified table. + * @param tableId The ID of the table for which to retrieve the key schema. + * @return keySchema The schema for keys in the specified table. + */ function getKeySchema(ResourceId tableId) internal view returns (Schema keySchema) { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { @@ -94,6 +135,15 @@ library StoreSwitch { } } + /** + * @dev Registers a table with specified configurations. + * @param tableId The ID of the table to register. + * @param fieldLayout The layout of the fields for the table. + * @param keySchema The schema for keys in the table. + * @param valueSchema The schema for values in the table. + * @param keyNames Names of keys in the table. + * @param fieldNames Names of fields in the table. + */ function registerTable( ResourceId tableId, FieldLayout fieldLayout, @@ -110,6 +160,14 @@ library StoreSwitch { } } + /** + * @dev Sets a record in the store. + * @param tableId The table's ID. + * @param keyTuple Array of key values. + * @param staticData Fixed-length fields data. + * @param encodedLengths Encoded lengths for dynamic data. + * @param dynamicData Dynamic-length fields data. + */ function setRecord( ResourceId tableId, bytes32[] memory keyTuple, @@ -125,6 +183,13 @@ library StoreSwitch { } } + /** + * @dev Splices the static (fixed length) data for a given table ID and key tuple, starting at a specific point. + * @param tableId The ID of the resource table. + * @param keyTuple An array of bytes32 keys identifying the data record. + * @param start The position to begin splicing. + * @param data The data to splice into the record. + */ function spliceStaticData(ResourceId tableId, bytes32[] memory keyTuple, uint48 start, bytes memory data) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { @@ -134,6 +199,15 @@ library StoreSwitch { } } + /** + * @dev Splices the dynamic data for a given table ID, key tuple, and dynamic field index. + * @param tableId The ID of the resource table. + * @param keyTuple An array of bytes32 keys identifying the data record. + * @param dynamicFieldIndex The index of the dynamic field to splice. + * @param startWithinField The position within the dynamic field to start splicing. + * @param deleteCount The number of bytes to delete starting from the splice point. + * @param data The data to splice into the dynamic field. + */ function spliceDynamicData( ResourceId tableId, bytes32[] memory keyTuple, @@ -157,6 +231,13 @@ library StoreSwitch { } } + /** + * @dev Sets the data for a specific field in a record identified by table ID and key tuple. + * @param tableId The ID of the resource table. + * @param keyTuple An array of bytes32 keys identifying the data record. + * @param fieldIndex The index of the field to set. + * @param data The data to set for the field. + */ function setField(ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, bytes memory data) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { @@ -166,6 +247,14 @@ library StoreSwitch { } } + /** + * @dev Sets the data for a specific field in a record, considering a specific field layout. + * @param tableId The ID of the resource table. + * @param keyTuple An array of bytes32 keys identifying the data record. + * @param fieldIndex The index of the field to set. + * @param data The data to set for the field. + * @param fieldLayout The layout structure of the field. + */ function setField( ResourceId tableId, bytes32[] memory keyTuple, @@ -181,6 +270,14 @@ library StoreSwitch { } } + /** + * @dev Sets the data for a specific static (fixed length) field in a record, considering a specific field layout. + * @param tableId The ID of the resource table. + * @param keyTuple An array of bytes32 keys identifying the data record. + * @param fieldIndex The index of the field to set. + * @param data The data to set for the field. + * @param fieldLayout The layout structure of the field. + */ function setStaticField( ResourceId tableId, bytes32[] memory keyTuple, @@ -196,6 +293,13 @@ library StoreSwitch { } } + /** + * @dev Sets the value of a specific dynamic (variable-length) field in a record. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param dynamicFieldIndex The index of the dynamic field to set. + * @param data The data to set for the field. + */ function setDynamicField( ResourceId tableId, bytes32[] memory keyTuple, @@ -210,6 +314,13 @@ library StoreSwitch { } } + /** + * @dev Appends data to a specific dynamic (variable length) field of a record. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param dynamicFieldIndex The index of the dynamic field. + * @param dataToPush The data to append to the field. + */ function pushToDynamicField( ResourceId tableId, bytes32[] memory keyTuple, @@ -224,6 +335,13 @@ library StoreSwitch { } } + /** + * @dev Removes data from the end of a specific dynamic (variable length) field of a record. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param dynamicFieldIndex The index of the dynamic field. + * @param byteLengthToPop The number of bytes to remove from the end of the field. + */ function popFromDynamicField( ResourceId tableId, bytes32[] memory keyTuple, @@ -238,6 +356,11 @@ library StoreSwitch { } } + /** + * @dev Deletes a record from a table. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + */ function deleteRecord(ResourceId tableId, bytes32[] memory keyTuple) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { @@ -247,6 +370,14 @@ library StoreSwitch { } } + /** + * @dev Retrieves a record from a table. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @return staticData The static data of the record. + * @return encodedLengths Encoded lengths of dynamic data. + * @return dynamicData The dynamic data of the record. + */ function getRecord( ResourceId tableId, bytes32[] memory keyTuple @@ -259,6 +390,15 @@ library StoreSwitch { } } + /** + * @dev Retrieves a record from a table with a specific layout. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param fieldLayout The layout of the fields in the record. + * @return staticData The static data of the record. + * @return encodedLengths Encoded lengths of dynamic data. + * @return dynamicData The dynamic data of the record. + */ function getRecord( ResourceId tableId, bytes32[] memory keyTuple, @@ -272,6 +412,13 @@ library StoreSwitch { } } + /** + * @dev Retrieves a specific field from a record. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param fieldIndex The index of the field to retrieve. + * @return Returns the data of the specified field. + */ function getField( ResourceId tableId, bytes32[] memory keyTuple, @@ -285,6 +432,14 @@ library StoreSwitch { } } + /** + * @dev Retrieves a specific field from a record with a given layout. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param fieldIndex The index of the field to retrieve. + * @param fieldLayout The layout of the field being retrieved. + * @return Returns the data of the specified field. + */ function getField( ResourceId tableId, bytes32[] memory keyTuple, @@ -299,6 +454,14 @@ library StoreSwitch { } } + /** + * @dev Retrieves a specific static (fixed length) field from a record with a given layout. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param fieldIndex The index of the static field to retrieve. + * @param fieldLayout The layout of the static field being retrieved. + * @return Returns the data of the specified static field. + */ function getStaticField( ResourceId tableId, bytes32[] memory keyTuple, @@ -313,6 +476,13 @@ library StoreSwitch { } } + /** + * @dev Retrieves a specific dynamic (variable length) field from a record. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param dynamicFieldIndex The index of the dynamic field to retrieve. + * @return Returns the data of the specified dynamic field. + */ function getDynamicField( ResourceId tableId, bytes32[] memory keyTuple, @@ -326,6 +496,13 @@ library StoreSwitch { } } + /** + * @dev Retrieves the length of a specific field in a record. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param fieldIndex The index of the field whose length is to be retrieved. + * @return Returns the length of the specified field. + */ function getFieldLength( ResourceId tableId, bytes32[] memory keyTuple, @@ -339,6 +516,14 @@ library StoreSwitch { } } + /** + * @dev Retrieves the length of a specific field in a record with a given layout. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param fieldIndex The index of the field whose length is to be retrieved. + * @param fieldLayout The layout of the field whose length is to be retrieved. + * @return Returns the length of the specified field. + */ function getFieldLength( ResourceId tableId, bytes32[] memory keyTuple, @@ -353,6 +538,13 @@ library StoreSwitch { } } + /** + * @dev Retrieves the length of a specific dynamic (variable length) field in a record. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param dynamicFieldIndex The index of the dynamic field whose length is to be retrieved. + * @return Returns the length of the specified dynamic field. + */ function getDynamicFieldLength( ResourceId tableId, bytes32[] memory keyTuple, @@ -366,6 +558,15 @@ library StoreSwitch { } } + /** + * @dev Retrieves a slice of a dynamic (variable length) field from a record. + * @param tableId The ID of the table to which the record belongs. + * @param keyTuple An array representing the key for the record. + * @param dynamicFieldIndex The index of the dynamic field from which to get the slice. + * @param start The starting index of the slice. + * @param end The ending index of the slice. + * @return Returns the sliced data from the specified dynamic field. + */ function getDynamicFieldSlice( ResourceId tableId, bytes32[] memory keyTuple,