Skip to content

Commit

Permalink
fix(ext/kv): reverse mapping between AnyValue::Bool and `KeyPart::B…
Browse files Browse the repository at this point in the history
…ool` (denoland#18365)

Previously the mapping between `AnyValue::Bool` and `KeyPart::Bool` was
inverted.

This patch also allows using the empty key `[]` as range start/end to
`snapshot_read`.
  • Loading branch information
losfair committed Mar 22, 2023
1 parent a117d3d commit 533e331
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 20 deletions.
28 changes: 28 additions & 0 deletions cli/tests/unit/kv_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,14 @@ dbTest("list prefix with end empty", async (db) => {
assertEquals(entries.length, 0);
});

dbTest("list prefix with empty prefix", async (db) => {
await db.set(["a"], 1);
const entries = await collect(db.list({ prefix: [] }));
assertEquals(entries, [
{ key: ["a"], value: 1, versionstamp: "00000000000000010000" },
]);
});

dbTest("list prefix reverse", async (db) => {
await setupData(db);

Expand Down Expand Up @@ -966,3 +974,23 @@ dbTest("invalid mutation type rejects", async (db) => {
.commit();
}, TypeError);
});

dbTest("key ordering", async (db) => {
await db.atomic()
.set([new Uint8Array(0x1)], 0)
.set(["a"], 0)
.set([1n], 0)
.set([3.14], 0)
.set([false], 0)
.set([true], 0)
.commit();

assertEquals((await collect(db.list({ prefix: [] }))).map((x) => x.key), [
[new Uint8Array(0x1)],
["a"],
[1n],
[3.14],
[false],
[true],
]);
});
16 changes: 0 additions & 16 deletions ext/kv/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ pub fn canonicalize_f64(n: f64) -> f64 {
}

pub fn encode_key(key: &Key) -> std::io::Result<Vec<u8>> {
// Disallow empty key
if key.0.is_empty() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"key should not be empty",
));
}

let mut output: Vec<u8> = vec![];
for part in &key.0 {
match part {
Expand Down Expand Up @@ -73,14 +65,6 @@ pub fn encode_key(key: &Key) -> std::io::Result<Vec<u8>> {
}

pub fn decode_key(mut bytes: &[u8]) -> std::io::Result<Key> {
// Disallow empty key
if bytes.is_empty() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"key should not be empty",
));
}

let mut key = Key(vec![]);
while !bytes.is_empty() {
let tag = bytes[0];
Expand Down
18 changes: 14 additions & 4 deletions ext/kv/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ type KvKey = Vec<AnyValue>;
impl From<AnyValue> for KeyPart {
fn from(value: AnyValue) -> Self {
match value {
AnyValue::Bool(false) => KeyPart::True,
AnyValue::Bool(true) => KeyPart::False,
AnyValue::Bool(false) => KeyPart::False,
AnyValue::Bool(true) => KeyPart::True,
AnyValue::Number(n) => KeyPart::Float(n),
AnyValue::BigInt(n) => KeyPart::Int(n),
AnyValue::String(s) => KeyPart::String(s),
Expand All @@ -115,8 +115,8 @@ impl From<AnyValue> for KeyPart {
impl From<KeyPart> for AnyValue {
fn from(value: KeyPart) -> Self {
match value {
KeyPart::True => AnyValue::Bool(false),
KeyPart::False => AnyValue::Bool(true),
KeyPart::False => AnyValue::Bool(false),
KeyPart::True => AnyValue::Bool(true),
KeyPart::Float(n) => AnyValue::Number(n),
KeyPart::Int(n) => AnyValue::BigInt(n),
KeyPart::String(s) => AnyValue::String(s),
Expand Down Expand Up @@ -499,6 +499,16 @@ where
resource.db.clone()
};

for key in checks
.iter()
.map(|c| &c.0)
.chain(mutations.iter().map(|m| &m.0))
{
if key.is_empty() {
return Err(type_error("key cannot be empty"));
}
}

let checks = checks
.into_iter()
.map(TryInto::try_into)
Expand Down

0 comments on commit 533e331

Please sign in to comment.