I am trying to understand a SQL line code at a RoR app. Does anybody know what ::int[] means? It appears at each "case" after "and".
case
when (array_length(array_remove(company_profiles.blocked_trails_ids,null),1) IS NOT NULL) and array[trails.id]::int[] && array_remove(company_profiles.blocked_trails_ids,null) then
false
else
true
end and
case
when (array_length(array_remove(company_profiles.blocked_components_ids,null),1) IS NOT NULL) and array[components.id]::int[]&& array_remove(company_profiles.blocked_components_ids,null) then
false
else
true
end and
case
when (array_length(array_remove(company_profiles.blocked_academies_ids,null),1) IS NOT NULL) and array[academies.id]::int[] && array_remove(company_profiles.blocked_academies_ids,null) then
false
else
true
end
In PostgreSQL, every data type has a companion array type. If you define your own data type, PostgreSQL creates a corresponding array type in the background for you. For example, integer has an integer array type integer[], character has a character array type character[], and so forth.
The :: is a type cast, a conversion from one data type to another.
Notice this line array[components.id]::int[]&& array_remove(...) might not work as expected.
Related
I've been getting really confused with this app I'm building. I'm trying to pass a parameter to a different scene. When I try to access the passed in value from the new scene, I can't use it. I keep getting the error "bad argument #1 to 'find' (string expected, got table)"
When I try to convert the value from a table to string, I get "bad argument #1 to 'concat' (table expected, got string)". I'm pretty new to Lua, so any help would be very appreciated. Here is some relevant code.
Scene1:
local function gotoOpt()
scene:removeEventListener( "create", scene )
local customParams = {
var1 = "scene3"
}
composer.gotoScene( "scene2", { effect="fade", time=1, params=customParams })
end
Scene2:
function scene:create( event )
local sceneGroup = self.view
print(event.params.var1 == string)
print(event.params.var1 == table)
print(type(event.params.var1))
print(type(event.params.var1) == string)
end
The results of the four print commands are as follows:
false
false
string
false
I cant really say anything about your problems with find and concat without seeing how you use them, although for me I've got problems in the past when mixing up sting.find and :find, which CAN give some of those errors.
But regarding types, type(something) returns a string indicating a type ("string", "boolean", "table", etc), so any comparisons need to compare to a string to be true, which is why your type comparisons return false when you don't expect it.
I have a lua script with code block as below:
local call_data = cjson.decode(ARGV[1])
local other_data = cjson.decode(ARGV[2])
local data = {}
local next = next
local populate_data = function(source)
if next(source) == nil then
return
end
for property,value in pairs(source) do
redis.call('HSET', KEYS[2], property, value)
end
end
populate_data(call_data)
populate_data(other_data)
When I try to run the script with the following command KEYS and ARGV as:-
redis-cli --eval dialed.lua "inflight_stats:18" "calls:AC443d7a8111a96ba8074f54a71f0521ce:CA1ec49703eee1959471c71506f43bb42e:dialed" , "{\"from\":\"+18035224181\",\"to\":\"+919943413333\",\"sid\":\"CA1ec49703eee1959471c71506f43bb42e\",\"status\":\"queued\",\"direction\":\"outbound-api\",\"date_created\":null,\"account_sid\":\"AC443d8a8111a96ba8074f54a71f0521ce\"}" "{\"phone\":\"919943413333\",\"campaign_id\":18,\"caller_session_sid\":\"CA828b163153bf5cc301ef5285e38925f9\"}" 0
Error :-
(error) ERR Error running script (call to f_08dcc69ee8baa0200e0cf552948ab4bc338c9978): #user_script:11: #user_script: 11: Lua redis() command arguments must be strings or integers
TL;DR for values returned by cjson.decode(), use cjson.null to compare to JSON's null value.
Explanation: Lua uses nil in tables to mark deleted entries. If JSONinc nulls were converted to Lunatic nils, the decoded objects would be corrupt. Therefore, the cjson lib uses a lightweight userdata type to represent null/nil.
Your 'call_data' has a 'date_created' field that is null - that causes the error.
The funny thing is that Redis, like Lua, will not store a nil/null value, so you'll have to either ignore null values or use a special value in Redis to flag them.
Assuming you'll be ignoring them, here's one way around it:
local call_data = cjson.decode(ARGV[1])
local other_data = cjson.decode(ARGV[2])
local data = {}
local next = next
local null = cjson.null
local populate_data = function(source)
if next(source) == nil then
return
end
for property,value in pairs(source) do
if value ~= null then
redis.call('HSET', KEYS[2], property, value)
end
end
end
populate_data(call_data)
populate_data(other_data)
Also, a small optimization would be to batch the updates, like so:
local payload = {}
for property,value in pairs(source) do
if value ~= null then
table.insert(payload, property)
table.insert(payload, value)
end
end
redis.call('HSET', KEYS[2], unpack(payload))
P.S. if you want, look at ReJSON that I wrote - it is designed to help with what it appears that you're trying to do.
I would like to know if it's possible to select a value from a table, based on the argument of a function.
I've tried setting the value statically, and that returns the value. I would just like to do it using function arguments.
function CheckWeapon(ped, attachment)
for k,v in pairs(weapons)do
if GetHashKey(k) == GetSelectedPedWeapon(ped) then
print(v.attachment)
return v.attachment -- This needs to be based on the
-- argument "attachment"
end
end
return false
end
I would expect that if I supplied the argument "silencer" to this function, I would receive the corresponding value for silencer in the table. Instead it's nil. If I type return v.silencer manually, it works though.
In Lua you can index a table 2 ways.
As you have done you can use . such as sometable.key
but this is just syntactic sugar for the other method of indexing, sometable["key"]
both of these use the string key to index the table.
your code could look like:
function CheckWeapon(ped, key)-- where key is a string ie: "attachment"
for k,v in pairs(weapons)do
if GetHashKey(k) == GetSelectedPedWeapon(ped) then
print(v[key])
return v[key]
end
end
return false
end
using the sometable["key"] option also allows for keys that could not be accessed with . such as
sometable["my key"] -- note the space
sometable["1st_key"] -- note it begins with a number
json_array = [{"id":82,"access_token":"3d04ba958abffbbb69f79dd2e108729e"}]
if json_array[0].key?(:access_token)
return true
else
return false
end
Every time return false
If you are using rails, it should work just fine, if this is pure ruby then you need to be exact about the type of key,
in ruby json_array[0].key?(:access_token) will return false because the key is a string type in your json array and you are checking if the key exists as a symbol, so to make it work in your case you'll need
return json_array.first.key?("access_token")
you don't need to do if then to return true or false in this case, you can just return the result of the key check
This works in rails because with action controller parameters you can use either string or symbol representation to access the hash elements.
Hope this helps
It returns false because "access_token" is not the same as :access_token.
Try checking for the key "access_token" instead.
Instead of using long lists of arguments in my function definitions, I prefer to pass a few fixed parameters and a table of 'additional params' like this:
function:doit( text, params )
end
This is nice as it allows me to add new named parameters later without breaking old calls.
The problem I am experiencing occurs when I try to force default values for some of the params:
function:doit( text, params )
local font = params.font or native.systemBold
local fontSize = params.fontSize or 24
local emboss = params.emboss or true
-- ...
end
The above code works fine in all cases, except where I have passed in 'false' for emboss:
doit( "Test text", { fontSize = 32, emboss = false } )
The above code will result in emboss being set to true when I really wanted false.
To be clear, what I want is for the first non-NIL value to be assigned to emboss, instead I'm getting a first non-false and non-NIL.
To combat this problem I wrote a small piece of code to find the first non-NIL value in a table and to return that:
function firstNotNil( ... )
for i = 1, #arg do
local theArg = arg[i]
if(theArg ~= nil) then return theArg end
end
return nil
end
Using this function I would re-write the emboss assignment as follows:
local emboss = firstNotNil(params.emboss, true)
Now, this certainly works, but it seems so inefficient and over the top. I am hoping there is a more compact way of doing this.
Please note: I found this ruby construct which looked promising and I am hoping lua has something like it:
[c,b,a].detect { |i| i > 0 } -- Assign first non-zero in order: c,b,a
Lua's relational operators evaluate to the value of one of the operands (i.e. the value is not coerced to boolean) so you can get the equivalent of C's ternary operator by saying a and b or c. In your case, you want to use a if it's not nil and b otherwise, so a == nil and b or a:
local emboss = (params.emboss == nil) and true or params.emboss
Not as pretty as before, but you'd only need to do it for boolean parameters.
[snip - Lua code]
Now, this certainly works, but it seems so inefficient and over the top.
Please note: I found this ruby construct which looked promising and I am hoping lua has
something like it:
[c,b,a].detect { |i| i > 0 } -- Assign first non-zero in order: c,b,a
Your Lua function is no more over-the-top or inefficient. The Ruby construct is more succinct, in terms of source text, but the semantics are not really different from firstNotNil(c,b,a). Both constructs end up creating a list object, initialize it with a set of values, running that through a function that searches the list linearly.
In Lua you could skip the creation of the list object by using vararg expression with select:
function firstNotNil(...)
for i = 1, select('#',...) do
local theArg = select(i,...)
if theArg ~= nil then return theArg end
end
return nil
end
I am hoping there is a more compact way of doing this.
About the only way to do that would be to shorten the function name. ;)
If you really want to do it in a single line, you'll need something like this for a default value of true:
local emboss = params.emboss or (params.emboss == nil)
It's not very readable, but it works. (params.emboss == nil) evaluates to true when params.emboss is not set (when you would need a default value), otherwise it's false. So when params.emboss is false, the statement is false, and when it's true, the statement is true (true or false = true).
For a default of false, what you tried originally would work:
local emboss = params.emboss or false