Skip to content

Commit a520a11

Browse files
authored
Merge pull request #123 from karthik2804/redis/exec
Add support for redis `execute`
2 parents 379fa5c + 1c5cb2f commit a520a11

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

crates/spin-js-engine/src/js_sdk/modules/spinSdk.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ interface SpinSDK {
4444
send: (arg0: BaseHttpRequest) => HttpResponse
4545
}
4646
redis: {
47+
execute: (address: string, args: Array< ArrayBuffer | bigint>) => undefined | string | bigint | ArrayBuffer
4748
get: (address: string, key: string) => ArrayBuffer
4849
incr: (address: string, key: string) => bigint
4950
publish: (address: string, channel: string, value: ArrayBuffer) => undefined

crates/spin-js-engine/src/lib.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use {
1717
http_component,
1818
key_value::Store,
1919
outbound_http, redis,
20+
redis::RedisResult,
2021
},
2122
std::{
2223
collections::HashMap,
@@ -331,6 +332,73 @@ fn math_rand(context: &Context, _this: &Value, _args: &[Value]) -> Result<Value>
331332
context.value_from_f64(thread_rng().gen_range(0.0_f64..1.0))
332333
}
333334

335+
fn redis_exec(context: &Context, _this: &Value, args: &[Value]) -> Result<Value> {
336+
enum Parameter {
337+
Int64(i64),
338+
Binary(ByteBuf),
339+
}
340+
341+
match args {
342+
[address, command, arguments] => {
343+
let address = &deserialize_helper(address)?;
344+
let command = &deserialize_helper(command)?;
345+
let mut arg = vec![];
346+
if arguments.is_array() {
347+
let mut props = arguments.properties()?;
348+
while let Some(ref _x) = props.next_key()? {
349+
let val = props.next_value()?;
350+
if val.is_big_int() {
351+
let deserializer = &mut Deserializer::from(val.clone());
352+
let temp = i64::deserialize(deserializer)?;
353+
arg.push(Parameter::Int64(temp));
354+
} else if val.is_array_buffer() {
355+
let deserializer = &mut Deserializer::from(val.clone());
356+
let temp = ByteBuf::deserialize(deserializer)?;
357+
arg.push(Parameter::Binary(temp));
358+
} else {
359+
bail!("invalid argument type, must be bigint or arraybuffer")
360+
}
361+
}
362+
} else {
363+
bail!("invalid argument type, must be array")
364+
}
365+
let results = redis::execute(
366+
address,
367+
command,
368+
&arg.iter()
369+
.map(|arg| match arg {
370+
Parameter::Int64(v) => redis::RedisParameter::Int64(*v),
371+
Parameter::Binary(v) => redis::RedisParameter::Binary(v.deref()),
372+
})
373+
.collect::<Vec<_>>(),
374+
)
375+
.map_err(|_| anyhow!("Error executing Redis execute command"))?;
376+
let arr = context.array_value()?;
377+
for result in results.iter() {
378+
match result {
379+
RedisResult::Nil => arr.append_property(context.undefined_value()?)?,
380+
RedisResult::Status(val) => {
381+
arr.append_property(context.value_from_str(&val)?)?
382+
}
383+
RedisResult::Int64(val) => {
384+
arr.append_property(context.value_from_i64(val.to_owned())?)?
385+
}
386+
RedisResult::Binary(val) => {
387+
let mut serializer = Serializer::from_context(context)?;
388+
val.serialize(&mut serializer)?;
389+
arr.append_property(serializer.value)?;
390+
}
391+
}
392+
}
393+
return Ok(arr);
394+
}
395+
_ => bail!(
396+
"expected a three arguments (address, command, arguments), got {} arguments",
397+
args.len()
398+
),
399+
}
400+
}
401+
334402
fn redis_get(context: &Context, _this: &Value, args: &[Value]) -> Result<Value> {
335403
match args {
336404
[address, key] => {
@@ -680,6 +748,7 @@ fn do_init() -> Result<()> {
680748
redis.set_property("sadd", context.wrap_callback(redis_sadd)?)?;
681749
redis.set_property("smembers", context.wrap_callback(redis_smembers)?)?;
682750
redis.set_property("srem", context.wrap_callback(redis_srem)?)?;
751+
redis.set_property("execute", context.wrap_callback(redis_exec)?)?;
683752

684753
let kv = context.object_value()?;
685754
kv.set_property("open", context.wrap_callback(open_kv)?)?;

types/lib/modules/spinSdk.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface KvStore {
2727
interface SpinSDK {
2828
config: SpinConfig;
2929
redis: {
30+
execute: (address: string, args: Array<ArrayBuffer | bigint>) => undefined | string | bigint | ArrayBuffer;
3031
get: (address: string, key: string) => ArrayBuffer;
3132
incr: (address: string, key: string) => bigint;
3233
publish: (address: string, channel: string, value: ArrayBuffer) => undefined;

0 commit comments

Comments
 (0)