diff --git a/packages/cli/contracts/src/tables/Dynamics.sol b/packages/cli/contracts/src/tables/Dynamics.sol index 1241dc712b..8fe25f3f71 100644 --- a/packages/cli/contracts/src/tables/Dynamics.sol +++ b/packages/cli/contracts/src/tables/Dynamics.sol @@ -73,12 +73,23 @@ library Dynamics { StoreSwitch.registerSchema(_tableId, getSchema(), getKeySchema()); } + /** Register the table's schema (using the specified store) */ + function registerSchema(IStore _store) internal { + _store.registerSchema(_tableId, getSchema(), getKeySchema()); + } + /** Set the table's metadata */ function setMetadata() internal { (string memory _tableName, string[] memory _fieldNames) = getMetadata(); StoreSwitch.setMetadata(_tableId, _tableName, _fieldNames); } + /** Set the table's metadata (using the specified store) */ + function setMetadata(IStore _store) internal { + (string memory _tableName, string[] memory _fieldNames) = getMetadata(); + _store.setMetadata(_tableId, _tableName, _fieldNames); + } + /** Get staticB32 */ function getStaticB32(bytes32 key) internal view returns (bytes32[1] memory staticB32) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -88,6 +99,15 @@ library Dynamics { return toStaticArray_bytes32_1(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes32()); } + /** Get staticB32 (using the specified store) */ + function getStaticB32(IStore _store, bytes32 key) internal view returns (bytes32[1] memory staticB32) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 0); + return toStaticArray_bytes32_1(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes32()); + } + /** Set staticB32 */ function setStaticB32(bytes32 key, bytes32[1] memory staticB32) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -96,6 +116,14 @@ library Dynamics { StoreSwitch.setField(_tableId, _primaryKeys, 0, EncodeArray.encode(fromStaticArray_bytes32_1(staticB32))); } + /** Set staticB32 (using the specified store) */ + function setStaticB32(IStore _store, bytes32 key, bytes32[1] memory staticB32) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setField(_tableId, _primaryKeys, 0, EncodeArray.encode(fromStaticArray_bytes32_1(staticB32))); + } + /** Push an element to staticB32 */ function pushStaticB32(bytes32 key, bytes32 _element) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -104,6 +132,14 @@ library Dynamics { StoreSwitch.pushToField(_tableId, _primaryKeys, 0, abi.encodePacked((_element))); } + /** Push an element to staticB32 (using the specified store) */ + function pushStaticB32(IStore _store, bytes32 key, bytes32 _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.pushToField(_tableId, _primaryKeys, 0, abi.encodePacked((_element))); + } + /** Get staticI32 */ function getStaticI32(bytes32 key) internal view returns (int32[2] memory staticI32) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -113,6 +149,15 @@ library Dynamics { return toStaticArray_int32_2(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_int32()); } + /** Get staticI32 (using the specified store) */ + function getStaticI32(IStore _store, bytes32 key) internal view returns (int32[2] memory staticI32) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 1); + return toStaticArray_int32_2(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_int32()); + } + /** Set staticI32 */ function setStaticI32(bytes32 key, int32[2] memory staticI32) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -121,6 +166,14 @@ library Dynamics { StoreSwitch.setField(_tableId, _primaryKeys, 1, EncodeArray.encode(fromStaticArray_int32_2(staticI32))); } + /** Set staticI32 (using the specified store) */ + function setStaticI32(IStore _store, bytes32 key, int32[2] memory staticI32) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setField(_tableId, _primaryKeys, 1, EncodeArray.encode(fromStaticArray_int32_2(staticI32))); + } + /** Push an element to staticI32 */ function pushStaticI32(bytes32 key, int32 _element) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -129,6 +182,14 @@ library Dynamics { StoreSwitch.pushToField(_tableId, _primaryKeys, 1, abi.encodePacked((_element))); } + /** Push an element to staticI32 (using the specified store) */ + function pushStaticI32(IStore _store, bytes32 key, int32 _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.pushToField(_tableId, _primaryKeys, 1, abi.encodePacked((_element))); + } + /** Get staticU128 */ function getStaticU128(bytes32 key) internal view returns (uint128[3] memory staticU128) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -138,6 +199,15 @@ library Dynamics { return toStaticArray_uint128_3(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint128()); } + /** Get staticU128 (using the specified store) */ + function getStaticU128(IStore _store, bytes32 key) internal view returns (uint128[3] memory staticU128) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 2); + return toStaticArray_uint128_3(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint128()); + } + /** Set staticU128 */ function setStaticU128(bytes32 key, uint128[3] memory staticU128) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -146,6 +216,14 @@ library Dynamics { StoreSwitch.setField(_tableId, _primaryKeys, 2, EncodeArray.encode(fromStaticArray_uint128_3(staticU128))); } + /** Set staticU128 (using the specified store) */ + function setStaticU128(IStore _store, bytes32 key, uint128[3] memory staticU128) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setField(_tableId, _primaryKeys, 2, EncodeArray.encode(fromStaticArray_uint128_3(staticU128))); + } + /** Push an element to staticU128 */ function pushStaticU128(bytes32 key, uint128 _element) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -154,6 +232,14 @@ library Dynamics { StoreSwitch.pushToField(_tableId, _primaryKeys, 2, abi.encodePacked((_element))); } + /** Push an element to staticU128 (using the specified store) */ + function pushStaticU128(IStore _store, bytes32 key, uint128 _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.pushToField(_tableId, _primaryKeys, 2, abi.encodePacked((_element))); + } + /** Get staticAddrs */ function getStaticAddrs(bytes32 key) internal view returns (address[4] memory staticAddrs) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -163,6 +249,15 @@ library Dynamics { return toStaticArray_address_4(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_address()); } + /** Get staticAddrs (using the specified store) */ + function getStaticAddrs(IStore _store, bytes32 key) internal view returns (address[4] memory staticAddrs) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 3); + return toStaticArray_address_4(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_address()); + } + /** Set staticAddrs */ function setStaticAddrs(bytes32 key, address[4] memory staticAddrs) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -171,6 +266,14 @@ library Dynamics { StoreSwitch.setField(_tableId, _primaryKeys, 3, EncodeArray.encode(fromStaticArray_address_4(staticAddrs))); } + /** Set staticAddrs (using the specified store) */ + function setStaticAddrs(IStore _store, bytes32 key, address[4] memory staticAddrs) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setField(_tableId, _primaryKeys, 3, EncodeArray.encode(fromStaticArray_address_4(staticAddrs))); + } + /** Push an element to staticAddrs */ function pushStaticAddrs(bytes32 key, address _element) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -179,6 +282,14 @@ library Dynamics { StoreSwitch.pushToField(_tableId, _primaryKeys, 3, abi.encodePacked((_element))); } + /** Push an element to staticAddrs (using the specified store) */ + function pushStaticAddrs(IStore _store, bytes32 key, address _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.pushToField(_tableId, _primaryKeys, 3, abi.encodePacked((_element))); + } + /** Get staticBools */ function getStaticBools(bytes32 key) internal view returns (bool[5] memory staticBools) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -188,6 +299,15 @@ library Dynamics { return toStaticArray_bool_5(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bool()); } + /** Get staticBools (using the specified store) */ + function getStaticBools(IStore _store, bytes32 key) internal view returns (bool[5] memory staticBools) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 4); + return toStaticArray_bool_5(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bool()); + } + /** Set staticBools */ function setStaticBools(bytes32 key, bool[5] memory staticBools) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -196,6 +316,14 @@ library Dynamics { StoreSwitch.setField(_tableId, _primaryKeys, 4, EncodeArray.encode(fromStaticArray_bool_5(staticBools))); } + /** Set staticBools (using the specified store) */ + function setStaticBools(IStore _store, bytes32 key, bool[5] memory staticBools) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setField(_tableId, _primaryKeys, 4, EncodeArray.encode(fromStaticArray_bool_5(staticBools))); + } + /** Push an element to staticBools */ function pushStaticBools(bytes32 key, bool _element) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -204,6 +332,14 @@ library Dynamics { StoreSwitch.pushToField(_tableId, _primaryKeys, 4, abi.encodePacked((_element))); } + /** Push an element to staticBools (using the specified store) */ + function pushStaticBools(IStore _store, bytes32 key, bool _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.pushToField(_tableId, _primaryKeys, 4, abi.encodePacked((_element))); + } + /** Get u64 */ function getU64(bytes32 key) internal view returns (uint64[] memory u64) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -213,6 +349,15 @@ library Dynamics { return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint64()); } + /** Get u64 (using the specified store) */ + function getU64(IStore _store, bytes32 key) internal view returns (uint64[] memory u64) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 5); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint64()); + } + /** Set u64 */ function setU64(bytes32 key, uint64[] memory u64) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -221,6 +366,14 @@ library Dynamics { StoreSwitch.setField(_tableId, _primaryKeys, 5, EncodeArray.encode((u64))); } + /** Set u64 (using the specified store) */ + function setU64(IStore _store, bytes32 key, uint64[] memory u64) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setField(_tableId, _primaryKeys, 5, EncodeArray.encode((u64))); + } + /** Push an element to u64 */ function pushU64(bytes32 key, uint64 _element) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -229,6 +382,14 @@ library Dynamics { StoreSwitch.pushToField(_tableId, _primaryKeys, 5, abi.encodePacked((_element))); } + /** Push an element to u64 (using the specified store) */ + function pushU64(IStore _store, bytes32 key, uint64 _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.pushToField(_tableId, _primaryKeys, 5, abi.encodePacked((_element))); + } + /** Get str */ function getStr(bytes32 key) internal view returns (string memory str) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -238,6 +399,15 @@ library Dynamics { return (string(_blob)); } + /** Get str (using the specified store) */ + function getStr(IStore _store, bytes32 key) internal view returns (string memory str) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 6); + return (string(_blob)); + } + /** Set str */ function setStr(bytes32 key, string memory str) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -246,6 +416,14 @@ library Dynamics { StoreSwitch.setField(_tableId, _primaryKeys, 6, bytes((str))); } + /** Set str (using the specified store) */ + function setStr(IStore _store, bytes32 key, string memory str) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setField(_tableId, _primaryKeys, 6, bytes((str))); + } + /** Push a slice to str */ function pushStr(bytes32 key, string memory _slice) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -254,6 +432,14 @@ library Dynamics { StoreSwitch.pushToField(_tableId, _primaryKeys, 6, bytes((_slice))); } + /** Push a slice to str (using the specified store) */ + function pushStr(IStore _store, bytes32 key, string memory _slice) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.pushToField(_tableId, _primaryKeys, 6, bytes((_slice))); + } + /** Get b */ function getB(bytes32 key) internal view returns (bytes memory b) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -263,6 +449,15 @@ library Dynamics { return (bytes(_blob)); } + /** Get b (using the specified store) */ + function getB(IStore _store, bytes32 key) internal view returns (bytes memory b) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 7); + return (bytes(_blob)); + } + /** Set b */ function setB(bytes32 key, bytes memory b) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -271,6 +466,14 @@ library Dynamics { StoreSwitch.setField(_tableId, _primaryKeys, 7, bytes((b))); } + /** Set b (using the specified store) */ + function setB(IStore _store, bytes32 key, bytes memory b) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setField(_tableId, _primaryKeys, 7, bytes((b))); + } + /** Push a slice to b */ function pushB(bytes32 key, bytes memory _slice) internal { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -279,6 +482,14 @@ library Dynamics { StoreSwitch.pushToField(_tableId, _primaryKeys, 7, bytes((_slice))); } + /** Push a slice to b (using the specified store) */ + function pushB(IStore _store, bytes32 key, bytes memory _slice) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.pushToField(_tableId, _primaryKeys, 7, bytes((_slice))); + } + /** Get the full data */ function get(bytes32 key) internal view returns (DynamicsData memory _table) { bytes32[] memory _primaryKeys = new bytes32[](1); @@ -288,6 +499,15 @@ library Dynamics { return decode(_blob); } + /** Get the full data (using the specified store) */ + function get(IStore _store, bytes32 key) internal view returns (DynamicsData memory _table) { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + bytes memory _blob = _store.getRecord(_tableId, _primaryKeys, getSchema()); + return decode(_blob); + } + /** Set the full data using individual values */ function set( bytes32 key, @@ -308,6 +528,27 @@ library Dynamics { StoreSwitch.setRecord(_tableId, _primaryKeys, _data); } + /** Set the full data using individual values (using the specified store) */ + function set( + IStore _store, + bytes32 key, + bytes32[1] memory staticB32, + int32[2] memory staticI32, + uint128[3] memory staticU128, + address[4] memory staticAddrs, + bool[5] memory staticBools, + uint64[] memory u64, + string memory str, + bytes memory b + ) internal { + bytes memory _data = encode(staticB32, staticI32, staticU128, staticAddrs, staticBools, u64, str, b); + + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.setRecord(_tableId, _primaryKeys, _data); + } + /** Set the full data using the data struct */ function set(bytes32 key, DynamicsData memory _table) internal { set( @@ -323,45 +564,65 @@ library Dynamics { ); } + /** Set the full data using the data struct (using the specified store) */ + function set(IStore _store, bytes32 key, DynamicsData memory _table) internal { + set( + _store, + key, + _table.staticB32, + _table.staticI32, + _table.staticU128, + _table.staticAddrs, + _table.staticBools, + _table.u64, + _table.str, + _table.b + ); + } + /** Decode the tightly packed blob using this table's schema */ function decode(bytes memory _blob) internal view returns (DynamicsData memory _table) { // 0 is the total byte length of static data PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 0)); - uint256 _start; - uint256 _end = 32; + // Store trims the blob if dynamic fields are all empty + if (_blob.length > 0) { + uint256 _start; + // skip static data length + dynamic lengths word + uint256 _end = 32; - _start = _end; - _end += _encodedLengths.atIndex(0); - _table.staticB32 = toStaticArray_bytes32_1(SliceLib.getSubslice(_blob, _start, _end).decodeArray_bytes32()); + _start = _end; + _end += _encodedLengths.atIndex(0); + _table.staticB32 = toStaticArray_bytes32_1(SliceLib.getSubslice(_blob, _start, _end).decodeArray_bytes32()); - _start = _end; - _end += _encodedLengths.atIndex(1); - _table.staticI32 = toStaticArray_int32_2(SliceLib.getSubslice(_blob, _start, _end).decodeArray_int32()); + _start = _end; + _end += _encodedLengths.atIndex(1); + _table.staticI32 = toStaticArray_int32_2(SliceLib.getSubslice(_blob, _start, _end).decodeArray_int32()); - _start = _end; - _end += _encodedLengths.atIndex(2); - _table.staticU128 = toStaticArray_uint128_3(SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint128()); + _start = _end; + _end += _encodedLengths.atIndex(2); + _table.staticU128 = toStaticArray_uint128_3(SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint128()); - _start = _end; - _end += _encodedLengths.atIndex(3); - _table.staticAddrs = toStaticArray_address_4(SliceLib.getSubslice(_blob, _start, _end).decodeArray_address()); + _start = _end; + _end += _encodedLengths.atIndex(3); + _table.staticAddrs = toStaticArray_address_4(SliceLib.getSubslice(_blob, _start, _end).decodeArray_address()); - _start = _end; - _end += _encodedLengths.atIndex(4); - _table.staticBools = toStaticArray_bool_5(SliceLib.getSubslice(_blob, _start, _end).decodeArray_bool()); + _start = _end; + _end += _encodedLengths.atIndex(4); + _table.staticBools = toStaticArray_bool_5(SliceLib.getSubslice(_blob, _start, _end).decodeArray_bool()); - _start = _end; - _end += _encodedLengths.atIndex(5); - _table.u64 = (SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint64()); + _start = _end; + _end += _encodedLengths.atIndex(5); + _table.u64 = (SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint64()); - _start = _end; - _end += _encodedLengths.atIndex(6); - _table.str = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + _start = _end; + _end += _encodedLengths.atIndex(6); + _table.str = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); - _start = _end; - _end += _encodedLengths.atIndex(7); - _table.b = (bytes(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + _start = _end; + _end += _encodedLengths.atIndex(7); + _table.b = (bytes(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + } } /** Tightly pack full data using this table's schema */ @@ -407,6 +668,14 @@ library Dynamics { StoreSwitch.deleteRecord(_tableId, _primaryKeys); } + + /* Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _primaryKeys = new bytes32[](1); + _primaryKeys[0] = bytes32((key)); + + _store.deleteRecord(_tableId, _primaryKeys); + } } function toStaticArray_bytes32_1(bytes32[] memory _value) pure returns (bytes32[1] memory _result) { diff --git a/packages/cli/contracts/src/tables/Singleton.sol b/packages/cli/contracts/src/tables/Singleton.sol index 90c29c60aa..c1b22c0a37 100644 --- a/packages/cli/contracts/src/tables/Singleton.sol +++ b/packages/cli/contracts/src/tables/Singleton.sol @@ -53,12 +53,23 @@ library Singleton { StoreSwitch.registerSchema(_tableId, getSchema(), getKeySchema()); } + /** Register the table's schema (using the specified store) */ + function registerSchema(IStore _store) internal { + _store.registerSchema(_tableId, getSchema(), getKeySchema()); + } + /** Set the table's metadata */ function setMetadata() internal { (string memory _tableName, string[] memory _fieldNames) = getMetadata(); StoreSwitch.setMetadata(_tableId, _tableName, _fieldNames); } + /** Set the table's metadata (using the specified store) */ + function setMetadata(IStore _store) internal { + (string memory _tableName, string[] memory _fieldNames) = getMetadata(); + _store.setMetadata(_tableId, _tableName, _fieldNames); + } + /** Get v1 */ function getV1() internal view returns (int256 v1) { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -67,6 +78,14 @@ library Singleton { return (int256(uint256(Bytes.slice32(_blob, 0)))); } + /** Get v1 (using the specified store) */ + function getV1(IStore _store) internal view returns (int256 v1) { + bytes32[] memory _primaryKeys = new bytes32[](0); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 0); + return (int256(uint256(Bytes.slice32(_blob, 0)))); + } + /** Set v1 */ function setV1(int256 v1) internal { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -74,6 +93,13 @@ library Singleton { StoreSwitch.setField(_tableId, _primaryKeys, 0, abi.encodePacked((v1))); } + /** Set v1 (using the specified store) */ + function setV1(IStore _store, int256 v1) internal { + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.setField(_tableId, _primaryKeys, 0, abi.encodePacked((v1))); + } + /** Get v2 */ function getV2() internal view returns (uint32[2] memory v2) { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -82,6 +108,14 @@ library Singleton { return toStaticArray_uint32_2(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint32()); } + /** Get v2 (using the specified store) */ + function getV2(IStore _store) internal view returns (uint32[2] memory v2) { + bytes32[] memory _primaryKeys = new bytes32[](0); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 1); + return toStaticArray_uint32_2(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint32()); + } + /** Set v2 */ function setV2(uint32[2] memory v2) internal { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -89,6 +123,13 @@ library Singleton { StoreSwitch.setField(_tableId, _primaryKeys, 1, EncodeArray.encode(fromStaticArray_uint32_2(v2))); } + /** Set v2 (using the specified store) */ + function setV2(IStore _store, uint32[2] memory v2) internal { + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.setField(_tableId, _primaryKeys, 1, EncodeArray.encode(fromStaticArray_uint32_2(v2))); + } + /** Push an element to v2 */ function pushV2(uint32 _element) internal { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -96,6 +137,13 @@ library Singleton { StoreSwitch.pushToField(_tableId, _primaryKeys, 1, abi.encodePacked((_element))); } + /** Push an element to v2 (using the specified store) */ + function pushV2(IStore _store, uint32 _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.pushToField(_tableId, _primaryKeys, 1, abi.encodePacked((_element))); + } + /** Get v3 */ function getV3() internal view returns (uint32[2] memory v3) { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -104,6 +152,14 @@ library Singleton { return toStaticArray_uint32_2(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint32()); } + /** Get v3 (using the specified store) */ + function getV3(IStore _store) internal view returns (uint32[2] memory v3) { + bytes32[] memory _primaryKeys = new bytes32[](0); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 2); + return toStaticArray_uint32_2(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint32()); + } + /** Set v3 */ function setV3(uint32[2] memory v3) internal { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -111,6 +167,13 @@ library Singleton { StoreSwitch.setField(_tableId, _primaryKeys, 2, EncodeArray.encode(fromStaticArray_uint32_2(v3))); } + /** Set v3 (using the specified store) */ + function setV3(IStore _store, uint32[2] memory v3) internal { + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.setField(_tableId, _primaryKeys, 2, EncodeArray.encode(fromStaticArray_uint32_2(v3))); + } + /** Push an element to v3 */ function pushV3(uint32 _element) internal { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -118,6 +181,13 @@ library Singleton { StoreSwitch.pushToField(_tableId, _primaryKeys, 2, abi.encodePacked((_element))); } + /** Push an element to v3 (using the specified store) */ + function pushV3(IStore _store, uint32 _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.pushToField(_tableId, _primaryKeys, 2, abi.encodePacked((_element))); + } + /** Get v4 */ function getV4() internal view returns (uint32[1] memory v4) { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -126,6 +196,14 @@ library Singleton { return toStaticArray_uint32_1(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint32()); } + /** Get v4 (using the specified store) */ + function getV4(IStore _store) internal view returns (uint32[1] memory v4) { + bytes32[] memory _primaryKeys = new bytes32[](0); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 3); + return toStaticArray_uint32_1(SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint32()); + } + /** Set v4 */ function setV4(uint32[1] memory v4) internal { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -133,6 +211,13 @@ library Singleton { StoreSwitch.setField(_tableId, _primaryKeys, 3, EncodeArray.encode(fromStaticArray_uint32_1(v4))); } + /** Set v4 (using the specified store) */ + function setV4(IStore _store, uint32[1] memory v4) internal { + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.setField(_tableId, _primaryKeys, 3, EncodeArray.encode(fromStaticArray_uint32_1(v4))); + } + /** Push an element to v4 */ function pushV4(uint32 _element) internal { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -140,6 +225,13 @@ library Singleton { StoreSwitch.pushToField(_tableId, _primaryKeys, 3, abi.encodePacked((_element))); } + /** Push an element to v4 (using the specified store) */ + function pushV4(IStore _store, uint32 _element) internal { + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.pushToField(_tableId, _primaryKeys, 3, abi.encodePacked((_element))); + } + /** Get the full data */ function get() internal view returns (int256 v1, uint32[2] memory v2, uint32[2] memory v3, uint32[1] memory v4) { bytes32[] memory _primaryKeys = new bytes32[](0); @@ -148,6 +240,16 @@ library Singleton { return decode(_blob); } + /** Get the full data (using the specified store) */ + function get( + IStore _store + ) internal view returns (int256 v1, uint32[2] memory v2, uint32[2] memory v3, uint32[1] memory v4) { + bytes32[] memory _primaryKeys = new bytes32[](0); + + bytes memory _blob = _store.getRecord(_tableId, _primaryKeys, getSchema()); + return decode(_blob); + } + /** Set the full data using individual values */ function set(int256 v1, uint32[2] memory v2, uint32[2] memory v3, uint32[1] memory v4) internal { bytes memory _data = encode(v1, v2, v3, v4); @@ -157,6 +259,15 @@ library Singleton { StoreSwitch.setRecord(_tableId, _primaryKeys, _data); } + /** Set the full data using individual values (using the specified store) */ + function set(IStore _store, int256 v1, uint32[2] memory v2, uint32[2] memory v3, uint32[1] memory v4) internal { + bytes memory _data = encode(v1, v2, v3, v4); + + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.setRecord(_tableId, _primaryKeys, _data); + } + /** Decode the tightly packed blob using this table's schema */ function decode( bytes memory _blob @@ -166,20 +277,24 @@ library Singleton { v1 = (int256(uint256(Bytes.slice32(_blob, 0)))); - uint256 _start; - uint256 _end = 64; + // Store trims the blob if dynamic fields are all empty + if (_blob.length > 32) { + uint256 _start; + // skip static data length + dynamic lengths word + uint256 _end = 64; - _start = _end; - _end += _encodedLengths.atIndex(0); - v2 = toStaticArray_uint32_2(SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint32()); + _start = _end; + _end += _encodedLengths.atIndex(0); + v2 = toStaticArray_uint32_2(SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint32()); - _start = _end; - _end += _encodedLengths.atIndex(1); - v3 = toStaticArray_uint32_2(SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint32()); + _start = _end; + _end += _encodedLengths.atIndex(1); + v3 = toStaticArray_uint32_2(SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint32()); - _start = _end; - _end += _encodedLengths.atIndex(2); - v4 = toStaticArray_uint32_1(SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint32()); + _start = _end; + _end += _encodedLengths.atIndex(2); + v4 = toStaticArray_uint32_1(SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint32()); + } } /** Tightly pack full data using this table's schema */ @@ -211,6 +326,13 @@ library Singleton { StoreSwitch.deleteRecord(_tableId, _primaryKeys); } + + /* Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store) internal { + bytes32[] memory _primaryKeys = new bytes32[](0); + + _store.deleteRecord(_tableId, _primaryKeys); + } } function toStaticArray_uint32_2(uint32[] memory _value) pure returns (uint32[2] memory _result) { diff --git a/packages/cli/contracts/src/tables/Statics.sol b/packages/cli/contracts/src/tables/Statics.sol index 41200b231c..8fb9ff1024 100644 --- a/packages/cli/contracts/src/tables/Statics.sol +++ b/packages/cli/contracts/src/tables/Statics.sol @@ -79,12 +79,23 @@ library Statics { StoreSwitch.registerSchema(_tableId, getSchema(), getKeySchema()); } + /** Register the table's schema (using the specified store) */ + function registerSchema(IStore _store) internal { + _store.registerSchema(_tableId, getSchema(), getKeySchema()); + } + /** Set the table's metadata */ function setMetadata() internal { (string memory _tableName, string[] memory _fieldNames) = getMetadata(); StoreSwitch.setMetadata(_tableId, _tableName, _fieldNames); } + /** Set the table's metadata (using the specified store) */ + function setMetadata(IStore _store) internal { + (string memory _tableName, string[] memory _fieldNames) = getMetadata(); + _store.setMetadata(_tableId, _tableName, _fieldNames); + } + /** Get v1 */ function getV1( uint256 k1, @@ -108,6 +119,30 @@ library Statics { return (uint256(Bytes.slice32(_blob, 0))); } + /** Get v1 (using the specified store) */ + function getV1( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal view returns (uint256 v1) { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 0); + return (uint256(Bytes.slice32(_blob, 0))); + } + /** Set v1 */ function setV1(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, uint256 v1) internal { bytes32[] memory _primaryKeys = new bytes32[](7); @@ -122,6 +157,30 @@ library Statics { StoreSwitch.setField(_tableId, _primaryKeys, 0, abi.encodePacked((v1))); } + /** Set v1 (using the specified store) */ + function setV1( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + uint256 v1 + ) internal { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.setField(_tableId, _primaryKeys, 0, abi.encodePacked((v1))); + } + /** Get v2 */ function getV2( uint256 k1, @@ -145,6 +204,30 @@ library Statics { return (int32(uint32(Bytes.slice4(_blob, 0)))); } + /** Get v2 (using the specified store) */ + function getV2( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal view returns (int32 v2) { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 1); + return (int32(uint32(Bytes.slice4(_blob, 0)))); + } + /** Set v2 */ function setV2(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, int32 v2) internal { bytes32[] memory _primaryKeys = new bytes32[](7); @@ -159,6 +242,30 @@ library Statics { StoreSwitch.setField(_tableId, _primaryKeys, 1, abi.encodePacked((v2))); } + /** Set v2 (using the specified store) */ + function setV2( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + int32 v2 + ) internal { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.setField(_tableId, _primaryKeys, 1, abi.encodePacked((v2))); + } + /** Get v3 */ function getV3( uint256 k1, @@ -182,6 +289,30 @@ library Statics { return (Bytes.slice16(_blob, 0)); } + /** Get v3 (using the specified store) */ + function getV3( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal view returns (bytes16 v3) { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 2); + return (Bytes.slice16(_blob, 0)); + } + /** Set v3 */ function setV3(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, bytes16 v3) internal { bytes32[] memory _primaryKeys = new bytes32[](7); @@ -196,6 +327,30 @@ library Statics { StoreSwitch.setField(_tableId, _primaryKeys, 2, abi.encodePacked((v3))); } + /** Set v3 (using the specified store) */ + function setV3( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + bytes16 v3 + ) internal { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.setField(_tableId, _primaryKeys, 2, abi.encodePacked((v3))); + } + /** Get v4 */ function getV4( uint256 k1, @@ -219,6 +374,30 @@ library Statics { return (address(Bytes.slice20(_blob, 0))); } + /** Get v4 (using the specified store) */ + function getV4( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal view returns (address v4) { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 3); + return (address(Bytes.slice20(_blob, 0))); + } + /** Set v4 */ function setV4(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, address v4) internal { bytes32[] memory _primaryKeys = new bytes32[](7); @@ -233,6 +412,30 @@ library Statics { StoreSwitch.setField(_tableId, _primaryKeys, 3, abi.encodePacked((v4))); } + /** Set v4 (using the specified store) */ + function setV4( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + address v4 + ) internal { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.setField(_tableId, _primaryKeys, 3, abi.encodePacked((v4))); + } + /** Get v5 */ function getV5( uint256 k1, @@ -256,6 +459,30 @@ library Statics { return (_toBool(uint8(Bytes.slice1(_blob, 0)))); } + /** Get v5 (using the specified store) */ + function getV5( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal view returns (bool v5) { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 4); + return (_toBool(uint8(Bytes.slice1(_blob, 0)))); + } + /** Set v5 */ function setV5(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, bool v5) internal { bytes32[] memory _primaryKeys = new bytes32[](7); @@ -270,6 +497,30 @@ library Statics { StoreSwitch.setField(_tableId, _primaryKeys, 4, abi.encodePacked((v5))); } + /** Set v5 (using the specified store) */ + function setV5( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + bool v5 + ) internal { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.setField(_tableId, _primaryKeys, 4, abi.encodePacked((v5))); + } + /** Get v6 */ function getV6( uint256 k1, @@ -293,6 +544,30 @@ library Statics { return Enum1(uint8(Bytes.slice1(_blob, 0))); } + /** Get v6 (using the specified store) */ + function getV6( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal view returns (Enum1 v6) { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 5); + return Enum1(uint8(Bytes.slice1(_blob, 0))); + } + /** Set v6 */ function setV6(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, Enum1 v6) internal { bytes32[] memory _primaryKeys = new bytes32[](7); @@ -307,6 +582,30 @@ library Statics { StoreSwitch.setField(_tableId, _primaryKeys, 5, abi.encodePacked(uint8(v6))); } + /** Set v6 (using the specified store) */ + function setV6( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + Enum1 v6 + ) internal { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.setField(_tableId, _primaryKeys, 5, abi.encodePacked(uint8(v6))); + } + /** Get v7 */ function getV7( uint256 k1, @@ -330,6 +629,30 @@ library Statics { return Enum2(uint8(Bytes.slice1(_blob, 0))); } + /** Get v7 (using the specified store) */ + function getV7( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal view returns (Enum2 v7) { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + bytes memory _blob = _store.getField(_tableId, _primaryKeys, 6); + return Enum2(uint8(Bytes.slice1(_blob, 0))); + } + /** Set v7 */ function setV7(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, Enum2 v7) internal { bytes32[] memory _primaryKeys = new bytes32[](7); @@ -344,6 +667,30 @@ library Statics { StoreSwitch.setField(_tableId, _primaryKeys, 6, abi.encodePacked(uint8(v7))); } + /** Set v7 (using the specified store) */ + function setV7( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + Enum2 v7 + ) internal { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.setField(_tableId, _primaryKeys, 6, abi.encodePacked(uint8(v7))); + } + /** Get the full data */ function get( uint256 k1, @@ -367,6 +714,30 @@ library Statics { return decode(_blob); } + /** Get the full data (using the specified store) */ + function get( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal view returns (StaticsData memory _table) { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + bytes memory _blob = _store.getRecord(_tableId, _primaryKeys, getSchema()); + return decode(_blob); + } + /** Set the full data using individual values */ function set( uint256 k1, @@ -398,6 +769,38 @@ library Statics { StoreSwitch.setRecord(_tableId, _primaryKeys, _data); } + /** Set the full data using individual values (using the specified store) */ + function set( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + uint256 v1, + int32 v2, + bytes16 v3, + address v4, + bool v5, + Enum1 v6, + Enum2 v7 + ) internal { + bytes memory _data = encode(v1, v2, v3, v4, v5, v6, v7); + + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.setRecord(_tableId, _primaryKeys, _data); + } + /** Set the full data using the data struct */ function set( uint256 k1, @@ -412,6 +815,37 @@ library Statics { set(k1, k2, k3, k4, k5, k6, k7, _table.v1, _table.v2, _table.v3, _table.v4, _table.v5, _table.v6, _table.v7); } + /** Set the full data using the data struct (using the specified store) */ + function set( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7, + StaticsData memory _table + ) internal { + set( + _store, + k1, + k2, + k3, + k4, + k5, + k6, + k7, + _table.v1, + _table.v2, + _table.v3, + _table.v4, + _table.v5, + _table.v6, + _table.v7 + ); + } + /** Decode the tightly packed blob using this table's schema */ function decode(bytes memory _blob) internal pure returns (StaticsData memory _table) { _table.v1 = (uint256(Bytes.slice32(_blob, 0))); @@ -455,6 +889,29 @@ library Statics { StoreSwitch.deleteRecord(_tableId, _primaryKeys); } + + /* Delete all data for given keys (using the specified store) */ + function deleteRecord( + IStore _store, + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + Enum1 k6, + Enum2 k7 + ) internal { + bytes32[] memory _primaryKeys = new bytes32[](7); + _primaryKeys[0] = bytes32(uint256((k1))); + _primaryKeys[1] = bytes32(uint256(uint32((k2)))); + _primaryKeys[2] = bytes32((k3)); + _primaryKeys[3] = bytes32(bytes20((k4))); + _primaryKeys[4] = _boolToBytes32((k5)); + _primaryKeys[5] = bytes32(uint256(uint8(k6))); + _primaryKeys[6] = bytes32(uint256(uint8(k7))); + + _store.deleteRecord(_tableId, _primaryKeys); + } } function _toBool(uint8 value) pure returns (bool result) { diff --git a/packages/cli/contracts/test/Tablegen.t.sol b/packages/cli/contracts/test/Tablegen.t.sol index 96d679d965..1504ca3f58 100644 --- a/packages/cli/contracts/test/Tablegen.t.sol +++ b/packages/cli/contracts/test/Tablegen.t.sol @@ -33,6 +33,11 @@ contract TablegenTest is Test, StoreView { bytes32 key = keccak256("key"); + // using `get` before setting any data should return default empty values + DynamicsData memory emptyData; + assertEq(abi.encode(Dynamics.get(key)), abi.encode(emptyData)); + + // initialize values bool[5] memory staticBools = [true, false, true, true, false]; uint64[] memory u64 = new uint64[](5); u64[0] = 0; @@ -42,7 +47,7 @@ contract TablegenTest is Test, StoreView { u64[4] = type(uint64).max; string memory str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit,"; bytes memory b = hex"ff"; - + // combine them into a struct DynamicsData memory data = DynamicsData( [keccak256("value")], [int32(-123), 123], @@ -54,9 +59,11 @@ contract TablegenTest is Test, StoreView { b ); + // test that the record is set correctly Dynamics.set(key, data); assertEq(abi.encode(Dynamics.get(key)), abi.encode(data)); + // test setting single fields Dynamics.setStaticBools(key, staticBools); assertEq(abi.encode(Dynamics.getStaticBools(key)), abi.encode(staticBools)); diff --git a/packages/cli/src/render-solidity/record.ts b/packages/cli/src/render-solidity/record.ts index 7d394a63de..635096ec2b 100644 --- a/packages/cli/src/render-solidity/record.ts +++ b/packages/cli/src/render-solidity/record.ts @@ -99,16 +99,20 @@ function renderDecodeFunction({ structName, fields, staticFields, dynamicFields ${fieldNamePrefix}${field.name} = ${renderDecodeValueType(field, staticOffsets[index])}; ` )} - uint256 _start; - uint256 _end = ${totalStaticLength + 32}; - ${renderList( - dynamicFields, - (field, index) => ` - _start = _end; - _end += _encodedLengths.atIndex(${index}); - ${fieldNamePrefix}${field.name} = ${renderDecodeDynamicFieldPartial(field)}; - ` - )} + // Store trims the blob if dynamic fields are all empty + if (_blob.length > ${totalStaticLength}) { + uint256 _start; + // skip static data length + dynamic lengths word + uint256 _end = ${totalStaticLength + 32}; + ${renderList( + dynamicFields, + (field, index) => ` + _start = _end; + _end += _encodedLengths.atIndex(${index}); + ${fieldNamePrefix}${field.name} = ${renderDecodeDynamicFieldPartial(field)}; + ` + )} + } } `; } else { diff --git a/packages/store/gas-report.txt b/packages/store/gas-report.txt index 0bc2e43c46..2e56eb5ffa 100644 --- a/packages/store/gas-report.txt +++ b/packages/store/gas-report.txt @@ -17,7 +17,7 @@ (test/Mixed.t.sol) | store Mixed struct in storage (native solidity) [testMixed = mixed]: 92050 (test/Mixed.t.sol) | register Mixed schema [Mixed.registerSchema()]: 61173 (test/Mixed.t.sol) | set record in Mixed [Mixed.set({ key: key, u32: 1, u128: 2, a32: a32, s: s })]: 112013 -(test/Mixed.t.sol) | get record from Mixed [MixedData memory mixed = Mixed.get(key)]: 13374 +(test/Mixed.t.sol) | get record from Mixed [MixedData memory mixed = Mixed.get(key)]: 13400 (test/PackedCounter.t.sol) | get value at index of PackedCounter [packedCounter.atIndex(3)]: 261 (test/PackedCounter.t.sol) | set value at index of PackedCounter [packedCounter = packedCounter.setAtIndex(2, 5)]: 799 (test/PackedCounter.t.sol) | pack uint16 array into PackedCounter [PackedCounter packedCounter = PackedCounterLib.pack(counters)]: 2152 @@ -85,7 +85,7 @@ (test/StoreCore.t.sol) | get static record (2 slots) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 1580 (test/StoreCore.t.sol) | StoreCore: set table metadata [StoreCore.setMetadata(table, tableName, fieldNames)]: 251710 (test/StoreMetadata.t.sol) | set record in StoreMetadataTable [StoreMetadata.set({ tableId: tableId, tableName: tableName, abiEncodedFieldNames: abi.encode(fieldNames) })]: 250184 -(test/StoreMetadata.t.sol) | get record from StoreMetadataTable [StoreMetadataData memory metadata = StoreMetadata.get(tableId)]: 12110 +(test/StoreMetadata.t.sol) | get record from StoreMetadataTable [StoreMetadataData memory metadata = StoreMetadata.get(tableId)]: 12133 (test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 671 (test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 627 (test/Vector2.t.sol) | register Vector2 schema [Vector2.registerSchema()]: 57971 diff --git a/packages/store/src/tables/Mixed.sol b/packages/store/src/tables/Mixed.sol index 0500e30296..edd7d42507 100644 --- a/packages/store/src/tables/Mixed.sol +++ b/packages/store/src/tables/Mixed.sol @@ -303,16 +303,20 @@ library Mixed { _table.u128 = (uint128(Bytes.slice16(_blob, 4))); - uint256 _start; - uint256 _end = 52; - - _start = _end; - _end += _encodedLengths.atIndex(0); - _table.a32 = (SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint32()); - - _start = _end; - _end += _encodedLengths.atIndex(1); - _table.s = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + // Store trims the blob if dynamic fields are all empty + if (_blob.length > 20) { + uint256 _start; + // skip static data length + dynamic lengths word + uint256 _end = 52; + + _start = _end; + _end += _encodedLengths.atIndex(0); + _table.a32 = (SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint32()); + + _start = _end; + _end += _encodedLengths.atIndex(1); + _table.s = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + } } /** Tightly pack full data using this table's schema */ diff --git a/packages/store/src/tables/StoreMetadata.sol b/packages/store/src/tables/StoreMetadata.sol index 8b141af6dd..703791e341 100644 --- a/packages/store/src/tables/StoreMetadata.sol +++ b/packages/store/src/tables/StoreMetadata.sol @@ -228,16 +228,20 @@ library StoreMetadata { // 0 is the total byte length of static data PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 0)); - uint256 _start; - uint256 _end = 32; - - _start = _end; - _end += _encodedLengths.atIndex(0); - _table.tableName = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); - - _start = _end; - _end += _encodedLengths.atIndex(1); - _table.abiEncodedFieldNames = (bytes(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + // Store trims the blob if dynamic fields are all empty + if (_blob.length > 0) { + uint256 _start; + // skip static data length + dynamic lengths word + uint256 _end = 32; + + _start = _end; + _end += _encodedLengths.atIndex(0); + _table.tableName = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + + _start = _end; + _end += _encodedLengths.atIndex(1); + _table.abiEncodedFieldNames = (bytes(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + } } /** Tightly pack full data using this table's schema */