import { Util, RLP } from '.' enum Type { SET, GET, REMOVE, HAS, NEXT, CURRENT_KEY, CURRENT_VALUE, HAS_NEXT, RESET } // @ts-ignore @external("env", "_db") declare function _db(type: u64, arg1: u64, arg2: u64, arg3: u64, arg4: u64): u64; export class Entry { constructor(readonly key: ArrayBuffer, readonly value: ArrayBuffer) { } } export class Store{ static from(str: string): Store{ return new Store(Util.str2bin(str)); } constructor(readonly prefix: ArrayBuffer) { } private _key(key: K): ArrayBuffer{ return Util.concatBytes(this.prefix, RLP.encode(key)); } set(key: K, value: V): void { DB.set(this._key(key), RLP.encode(value)); } remove(key: K): void { DB.remove(this._key(key)); } has(key: K): bool { return DB.has(this._key(key)); } getOrDefault(key: K, def: V): V { return this.has(key) ? this.get(key) : def; } get(key: K): V { return RLP.decode(DB.get(this._key(key))); } } export class Globals{ static set(str: string, value: V): void { DB.set(Util.str2bin(str), RLP.encode(value)); } static get(str: string): V { return RLP.decode(DB.get(Util.str2bin(str))); } static getOrDefault(str: string, value: V): V { return DB.has(Util.str2bin(str)) ? RLP.decode(DB.get(Util.str2bin(str))) : value; } static has(str: string): bool { return DB.has(Util.str2bin(str)); } static remove(str: string): void{ DB.remove(Util.str2bin(str)); } } export class DB { static set(key: ArrayBuffer, value: ArrayBuffer): void { _db( Type.SET, changetype(key), key.byteLength, changetype(value), value.byteLength, ); } static remove(key: ArrayBuffer): void { _db( Type.REMOVE, changetype(key), key.byteLength, 0, 0, ); } static has(key: ArrayBuffer): bool { return _db(Type.HAS, changetype(key), key.byteLength, 0, 0) != 0; } static get(key: ArrayBuffer): ArrayBuffer { const len = _db(Type.GET, changetype(key), key.byteLength, 0, 0); const buf = new ArrayBuffer(i32(len)); _db(Type.GET, changetype(key), key.byteLength, changetype(buf), 1); return buf; } } export class DBIterator { static next(): Entry { _db(Type.NEXT, 0, 0, 0, 0); const keyBuf = new ArrayBuffer(i32(_db(Type.CURRENT_KEY, 0, 0, 0, 0))); _db(Type.CURRENT_KEY, changetype(keyBuf), 1, 0, 0); const valueBuf = new ArrayBuffer(i32(_db(Type.CURRENT_VALUE, 0, 0, 0, 0))); _db(Type.CURRENT_KEY, changetype(valueBuf), 1, 0, 0); return new Entry(keyBuf, valueBuf); } static hasNext(): bool { return _db(Type.HAS_NEXT, 0, 0, 0, 0) != 0; } static reset(): void { _db(Type.RESET, 0, 0, 0, 0); } }