Redis Lua script - how to pass array as argument to a Lua script in nodejs? - arrays

I am calling a Lua script from nodejs. I want to pass an array as argument. I am facing problem to parse that array in Lua.
Below is an example:
var script = 'local actorlist = ARGV[1]
if #actorlist > 0 then
for i, k in ipairs(actorlist) do
redis.call("ZADD","key", 1, k)
end
end';
client.eval(
script, //lua source
0,
['keyv1','keyv2']
function(err, result) {
console.log(err+'------------'+result);
}
);
It gives me this error:
"ERR Error running script (call to f_b263a24560e4252cf018189a4c46c40ce7d1b21a): #user_script:1: user_script:1: bad argument #1 to 'ipairs' (table expected, got string)

You can do it just by using ARGV:
local actorlist = ARGV
for i, k in ipairs(actorlist) do
and pass arguments in console like this:
eval "_script_" 0 arg1 arg2 argN

You can only pass in strings into Redis lua script.
If you need an array of values to be pass into Redis lua script, you can do this:
let script = `
if #ARVG > 0 then
for i, k in ipairs(ARGV) do
redis.call("ZADD","key", 1, k)
end
end`;
client.eval(
script, //lua source
0,
...['keyv1','keyv2'],
function(err, result) {
console.log(err+'------------'+result);
}
);
The key here is to pass keyv1 and keyv2 as a separate params when calling eval. (I am using es6 syntax here)

Related

Two Arrays in a single definition in Groovy

I have to pass two different parameters from my Jenkin job, to my groovy function . I am trying to read them in two different arrays as shown below. But somehow, it is not working. its working, if I pass only one parameter to one array.
Parameter 1 = imagelist1
parameter 2 = imagelist2
def abc = {
container('xyz') {
String[] arrspt = imagelist1.split(' ')
for(int i=0; i < arrspt.length; i++) {
env.image_name = arrspt[i]
sh 'echo "${image_name}" >> images_to_scan.txt'
}
String[] arrStr = imagelist2.split(' ')
for(int i=0; i < arrStr.length; i++) {
env.image_name2 = arrStr[i]
sh 'echo "${image_name2}" >> images_to_scan.txt
}
}
}
when I run the Jenkin Job, I am getting error as below :
[Pipeline] Start of Pipeline
[Pipeline] End of Pipeline
org.jenkinsci.plugins.workflow.cps.CpsCompilationErrorsException:
startup failed:
General error during class generation: Method too large:
Pipeline.___cps___19086323
()Lcom/cloudbees/groovy/cps/impl/CpsFunction;
groovyjarjarasm.asm.MethodTooLargeException: Method too large:
Pipeline.___cps___19086323
()Lcom/cloudbees/groovy/cps/impl/CpsFunction;`
Am I doing something wrong in declaring the 2 different arrays in Groovy?
Any help here is highly appreciated !

Array parameters to and from postgresql stored procedures using Npgsql from F#

I have two SQL functions (procedures) in postgresql. They take and return array; their signatures are
create function arr_ret( x int) returns int[] as
and
create function arr_param( x int[] ) returns int as
The first function when executed returns
> ctx.Functions.ArrRet.Invoke(6);;
Executing SQL : EXEC arr_ret(6) - params
val it : Unit = ()
>
As can be seen, the signature of the invoke operation is Unit() = (); doesn't return anything. I would have expected Unit() = int list because the procedure is expected to return an array of integers.
The second function when executed
> ctx.Functions.ArrParam.Invoke( [1;2;3;4;5;6] );;
ctx.Functions.ArrParam.Invoke( [1;2;3;4;5;6] );;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(22,1): error FS0501: The member or object constructor 'Invoke' takes 0 argument(s) but is here given 1. The requir
ed signature is 'SqlDataProvider<...>.dataContext.Functions.ArrParam.Result.Invoke() : SqlDataProvider<...>.dataContext.
Functions.ArrParam.Result.SprocResult'.
Npgsql is not seeing the parameter (either input or output) that is of array type. The documentation says postgresql array and composite types are supported from 3.0+ version and I am using the latest 3.2.3
You are sending a single argument of type FSharpList into a method that expects params. The way you are using it will send the entire list as a single parameter.
ctx.Functions.ArrParam.Invoke(1, 2, 3, 4, 5, 6);;
The above will send them individually as you want, but not if you pass the entire collection. The reason for this is the type provider is trying to resolve the type of object instead treating the entire array as multiple arguments.
In C#, this would work fine, but not in F#.
Here's a good way to test.
In C# define this method:
public static void PrintArgs(params object[] args)
{
foreach (var arg in args)
{
Console.WriteLine($"Type: {arg.GetType().Name}");
}
}
In F# call it as:
PrintArgs(1, 2.0, true, "4")
PrintArgs([1; 2; 3; 4])
They result in:
>
Type: Int32
Type: Double
Type: Boolean
Type: String
val it : unit = ()
>
Type: FSharpList`1
val it : unit = ()
>
Your problem is what happens in the second call, it's actually a List that's being sent and not multiple arguments.

nodejs print array elements all except first index

In NodeJS (latest), I'm able to print
console.log(args[0])
console.log(args[1])
console.log(args[2])
In my case, the function where I'm printing these arguments index variable is using NodeJS child.spawn(command,args) way i.e. a user can pass 1, 2 or 5 or N no. of arguments. As I don't know how many a user can set, I can't code the console.log() lines for that N no. of individual indexes.
How can I print all arguments except index args[0]?
Index args[1] contains the command name, which I'm able to print.
Index args[2] onwards, may contain args[2] = "-c", args[3]="param1", args[4]="paramX paramY" etc and so on depending upon how a user pushed arguments to args array in your .js file before calling the function which prints console.log lines.
I want to print the output like:
args[0] = /usr/bin/bash
args[XXX] = -c, param1, param2, param3 param4, param5 etc, etc-etc
As I say in comments, something like this is what you may want.
function func(...args){
args.forEach((el, i)=>i != 1 && console.log(el));
};
func('/usr/bin/bash', 'Something not used', '-c', 'param1', 'param2', 'param3');
If you're using arguments variable:
function func(){
// Equivalent to [...arguments]
Array.from(arguments).forEach((el, i)=>i != 1 && console.log(el));
};
func('/usr/bin/bash', 'Something not used', '-c', 'param1', 'param2', 'param3');
If I understood correctly, you are looking for something along these lines:
// wrap in function to mimic the arguments object
function execute() {
// declare a place to store the arguments
var result = []
// iterate through each argument
Array.from(arguments).forEach((value, key) => {
// skip the second key
if (key > 0) {
// store each argument in the result array
result.push(value)
}
})
// console log the result array as multiple arguments
console.log.apply(null, result) // -> /usr/bin/bash -c param1 param2 param3
}
// mock command
execute('/usr/bin/bash', 'command', '-c', 'param1', 'param2', 'param3')
I hope this helps!

Pass array parameter from external dll to Python

I tried to call a function from external DLL in Python.
The function prototype is:
void Myfunction(int32_t *ArraySize, uint64_t XmemData[])
This function creates a table of uint64 with "ArraySize" elements. This dll is generated by labview.
Here is the Python code to call this function:
import ctypes
# Load the library
dllhandle = ctypes.CDLL("SharedLib.dll")
#specify the parameter and return types
dllhandle.Myfunction.argtypes = [ctypes.c_int,ctypes.POINTER(ctypes.c_uint64)]
# Next, set the return types...
dllhandle.Myfunction.restype = None
#convert our Python data into C data
Array_Size = ctypes.c_int(10)
Array = (ctypes.c_uint64 * Array_Size.value)()
# Call function
dllhandle.Myfunction(Array_Size,Array)
for index, value in enumerate(Array):
print Array[index]
When executing this I got the error code:
dllhandle.ReadXmemBlock(Array_Size,Array)
WindowsError: exception: access violation reading 0x0000000A
I guess that I don't pass correctly the parameters to the function, but I can't figure it out.
I tried to sort simple data from the labview dll like a uint64, and that works fine; but as soon as I tried to pass arrays of uint64 I'm stuck.
Any help will be appreciated.
It looks like it's trying to access the memory address 0x0000000A (which is 10). This is because you're passing an int instead of a pointer to an int (although that's still an int), and you're making that int = 10.
I'd start with:
import ctypes
# Load the library
dllhandle = ctypes.CDLL("SharedLib.dll")
#specify the parameter and return types
dllhandle.Myfunction.argtypes = [POINTER(ctypes.c_int), # make this a pointer
ctypes.c_uint64 * 10]
# Next, set the return types...
dllhandle.Myfunction.restype = None
#convert our Python data into C data
Array_Size = ctypes.c_int(10)
Array = (ctypes.c_uint64 * Array_Size.value)()
# Call function
dllhandle.Myfunction(byref(Array_Size), Array) # pass pointer using byref
for index, value in enumerate(Array):
print Array[index]

How to pass index of array in cmd line argument which is function pointer and call to specific function in perl?

Suppose I have 2 functions in Perl. I would create a array of references of that two functions. & in command line argument I'll pass only that index of array which call specific function and if I don't give any argument then it'll call all functions which referenced were in array(Default case).
So, can any help me to do this?
## Array content function pointers
my #list= {$Ref0,$Ref1 }
my $fun0Name = “fun0”;
my $Ref0 =&{$fun0Name}();
my $fun1Name = “fun1”;
my $Ref1 =&{$fun1Name}();
#### Two functions
sub fun0() {
print "hi \n";
}
sub fun1() {
print "hello \n";
}
##### Now in cmd argument if i passed Test.pl -t 0(index of array ,means call to 1st function)
##### if i give test.pl -t (No option ) ....then i call both function.
Creating a function pointer (called a code reference in Perl) is easy enough:
sub foo {
say "foo!";
}
sub bar {
say "bar!";
}
my $foo_ref = \&foo;
my $bar_ref = \&bar;
Putting things in an array is pretty easy:
my #array = ( $foo_ref, $bar_ref );
Reading arguments from the command line is pretty easy:
my $arg = shift #ARGV;
Looking things up in an array is also pretty easy:
my $item = $array[$arg];
Which part are you having trouble with?

Resources