postgres json parameter to a function - json

CREATE OR REPLACE FUNCTION public.writecalculations(id integer, times integer, j json)
RETURNS text
LANGUAGE plv8
AS
$body$
var overallStart = new Date();
var result = 0;
var insertStmt = "Insert into \"CalculationResult\" Values($1,$2,$3::json)"
result += plv8.execute(insertStmt,[id, times, j]);
var loopEnd = new Date();
return JSON.stringify({"AffectedRows": result, "OverallRuntime": loopEnd-overallStart}) ;
$body$
IMMUTABLE STRICT
COST 100;
COMMIT;
This gives an error when executed using
WbCall calculationResult(4,4,'{\"a\":1}');
Error :
An error occurred when executing the SQL command:
ERROR: function calculationresult(integer, integer, unknown) does not exist
Hint: No function matches the given name and argument types. You might need >to add explicit type casts.
Position: 15 [SQL State=42883]
What am I doing wrong?
I tried various options of passing text with "" and '' and also as passing json

try:
WbCall calculationResult(4,4,'{"a":1}'::json);
calculationresult(integer, integer, unknown) - PostgreSQL didn't detect type of '{"a":1}', so it ask you to add explicit type casts.

Related

Jsony newHook has `SIGSEGV: Illegal storage access. (Attempt to read from nil?)` when deserializing into ref-objects

I am writing a web-application and am deserializing via jsony into norm-model-object types.
Norm-model-types are always ref objects. Somehow my code which is very similar to the default example in jsony's github documentation does not compile. Instead I receive the error SIGSEGV: Illegal storage access. (Attempt to read from nil?).
See here my code sample
import std/[typetraits, times]
import norm/[pragmas, model]
import jsony
const OUTPUT_TIME_FORMAT* = "yyyy-MM-dd'T'HH:mm:ss'.'ffffff'Z'"
type Character* {.tableName: "wikientries_character".} = ref object of Model
name*: string
creation_datetime*: DateTime
update_datetime*: DateTime
proc parseHook*(s: string, i: var int, v: var DateTime) =
##[ jsony-hook that is automatically called to convert a json-string to datetime
``s``: The full JSON string that needs to be serialized. Your type may only be a part of this
``i``: The index on the JSON string where the next section of it starts that needs to be serialized here
``v``: The variable to fill with a proper value]##
var str: string
s.parseHook(i, str)
v = parse(s, OUTPUT_TIME_FORMAT, utc())
proc newHook*(entry: var Character) =
let currentDateTime: DateTime = now()
entry.creation_datetime = currentDateTime # <-- This line is listed as the reason for the sigsev
entry.update_datetime = currentDateTime
entry.name = ""
var input = """ {"name":"Test"} """
let c = input.fromJson(Character)
I don't understand what the issue appears to be here, as the jsony-example on its github page looks pretty similar:
type
Foo5 = object
visible: string
id: string
proc newHook*(foo: var Foo5) =
# Populates the object before its fully deserialized.
foo.visible = "yes"
var s = """{"id":"123"}"""
var v = s.fromJson(Foo5)
doAssert v.id == "123"
doAssert v.visible == "yes"
How can I fix this?
The answer lies in the fact that norm-object-types are ref objects, not normal (value) objects (Thanks to ElegantBeef, Rika and Yardanico from the nim-discord to point this out)! If you do not explicitly 'create' a ref-type at one point, the memory for it is never allocated since the code doesn't do the memory allocation for you unlike with value types!
Therefore, you must initialize/create a ref-object first before you can use it, and Jsony does not take over initialization for you!
The correct way to write the above newHook thus looks like this:
proc newHook*(entry: var Character) =
entry = new(Character)
let currentDateTime: DateTime = now()
entry.creation_datetime = currentDateTime
entry.update_datetime = currentDateTime
entry.name = ""

String passed to JSON library turns into a table

When I execute this code (Windows 10) i get an error from within the library.
local json = loadfile("json.lua")()
local handle = io.popen("curl \"https://someurl.com\"")
local result = handle:read("*all")
handle:close()
local output = json:decode(result)
The error in the console:
lua: json.lua:377: expected argument of type string, got table
stack traceback:
[C]: in function 'error'
json.lua:377: in method 'decode'
monitor.lua:10: in main chunk
[C]: in ?
I'm running the code on Windows 10 with a console and using this library: https://github.com/rxi/json.lua
This function always returns the same error, even if I try different types of arguments, i.e. numbers or strings.
function json.decode(str)
if type(str) ~= "string" then
error("expected argument of type string, got " .. type(str))
end
local res, idx = parse(str, next_char(str, 1, space_chars, true))
idx = next_char(str, idx, space_chars, true)
if idx <= #str then
decode_error(str, idx, "trailing garbage")
end
return res
end
local output = json:decode(result)
is syntactic sugar for
local output = json.decode(json, result)
json is a table.
Hence inside function json.decode the following if statement is entered:
if type(str) ~= "string" then
error("expected argument of type string, got " .. type(str))
end
which produces the observed error.
To fix this you can either change the function definiton to
function json:decode(str)
-- code
end
Or you call
local output = json.decode(result)
You should pick the second one as changing the json library will affect code that already uses json.decode as intended by the author.

Freepascal procedure parameter of file type default value

A class method has a simple definition
PROCEDURE Print (str : string = ''; VAR f : text);
This gives the compiler error
Error: (3185) Default parameter required for "F"
This is strange because on this page it says "default values are not supported for variable parameters." Ignoring that, adding a default value:
PROCEDURE Print (str : string = ''; VAR f : text = stderr);
gives the compiler error
Error: (3203) Illegal expression
What is the correct syntax here (by correct I mean how can I make the compiler happy)?
Once a parameter have a default value all the parameters that follow must also have a default, this is why you have
Error: (3185) Default parameter required for "F"
At this point of the compilation, FPC didn't detect that, grammatically speaking, F couldn't have a default parameter, it just see that there is no default.
You declaration should rather be
PROCEDURE Print (VAR f : text; str : string = '');
To go further, let's take this function:
procedure foo(a: integer = 8; b: integer);
If you call it like this
foo(4);
The compiler wouldn't know if 4 is for a and you forget b or if 4 is for b. That's why default parameters must always be put at the end. That's also why FPC would emit the following error:
Error: Default parameter required for "B"
Additional to #Nestedtype explanation.
It can be solved using overloaded methods without changes in parameter order like
PROCEDURE Print (str : string; VAR f : text); overload; // Calls as Print('foo', f);
PROCEDURE Print (VAR f : text); overload; // Calls as Print(f);
and in the implementation section:
PROCEDURE Print (str : string; VAR f : text);
begin
// Do what you need
end;
PROCEDURE Print (VAR f : text);
begin
Print('', f); // Here '' is the "default" value
end;

ActionScript: Is there ever a good reason to use 'as' casting?

From what I understand of ActionScript, there are two kinds of casts:
var bar0:Bar = someObj as Bar; // "as" casting
var bar1:Bar = Bar(someObj); // "class name" casting (for want of a better name)
Also, and please correct me if I'm wrong here, as casting will either return an instance of the class or null, while "class name" casting will either return an instance of the class or raise an exception if the cast is impossible – other than this, they are identical.
Given this, though, as casting seems to be a massive violation of the fail-fast-fail-early principle... And I'm having trouble imagining a situation where it would be preferable to use an as cast rather than a class name cast (with, possibly, an instanceof thrown in there).
So, my question is: under what circumstances would it be preferable to use as casting?
There are a couple of points in this discussion worth noting.
There is a major difference in how the two work, Class() will attempt to cast the object to the specified Class, but on failure to do so will (sometimes, depends on datatype) throw a runtime error. On the other hand using object as Class will preform a type check first, and if the specified object cannot be cast to the indicated Class a null value is returned instead.
This is a very important difference, and is a useful tool in development. It allows us to do the following:
var o:MyClass = myArray[i] as MyClass;
if(o)
{
//do stuff
}
I think the usefulness of that is pretty obvious.
"as" is also more consistent with the rest of the language (ie: "myObject is MyClass").
The MyClass() method has additional benefits when working with simple data types (int, Number, uint, string) Some examples of this are:
var s:String = "89567";
var s2:String = "89 cat";
var n:Number = 1.9897;
var i:int = int(s); // i is = 89567, cast works
var i2:int = int(s2); //Can't convert so i2 is set to 0
var i3:int = int(n); // i = 1
var n2:Number = Number(s2); // fails, n2 = NaN
//when used in equations you'll get very different results
var result:int = int(n) * 10; //result is 10
var result:int = n * 10; //result is 19.89700
var result:int = int(s2) * 10; //result is 0
trace(s2 as Number); //outputs null
trace(s2 as int); //outputs null
trace(Number(s2)); //outputs NaN
This is a good and important topic, as a general rule I use "as" when working with Objects and Cast() when using simpler data types, but that's just how I like to structure my code.
You need to use as to cast in two scenarios: casting to a Date, and casting to an Array.
For dates, a call to Date(xxx) behaves the same as new Date().toString().
For arrays, a call to Array(xxx) will create an Array with one element: xxx.
The Class() casting method has been shown to be faster than as casting, so it may be preferable to as when efficiency matters (and when not working with Dates and Arrays).
import flash.utils.*;
var d = Date( 1 );
trace( "'" + d, "'is type of: ",getQualifiedClassName( d ) );
var a:Array = Array( d );
trace( "'" + a, "' is type of: ", getQualifiedClassName( a ) );
//OUTPUT
//'Mon Jun 15 12:12:14 GMT-0400 2009 'is type of: String
//'Mon Jun 15 12:12:14 GMT-0400 2009 ' is type of: Array
//COMPILER ERRORS/WARNINGS:
//Warning: 3575: Date(x) behaves the same as new Date().toString().
//To cast a value to type Date use "x as Date" instead of Date(x).
//Warning: 1112: Array(x) behaves the same as new Array(x).
//To cast a value to type Array use the expression x as Array instead of Array(x).
`
They actually do different things...when you say
myvar as ClassName
You are really just letting the compiler know that this object is either a ClassName or a subclass of ClassName
when you say:
ClassName(myvar)
It actually tries to convert it to that type of object.
so if your object is a or a descent of the class and you do not need to convert it you would use as
examples:
var myvar:String = '<data/>';
var othervar:XML = XML(myvar); //right
var myvar:String = '<data/>';
var othervar:XML = (myvar as XML); //wrong
var myvar:XML = <data/>;
var othervar:XML = myvar as XML; // right
Use 'as' with arrays.
var badArray:Array;
badArray = Array(obj);
Will yield an array of length one with the original array in the first element. If you use 'as' as follows, you get the exptected result.
var goodArray:Array;
goodArray = obj as Array;
Generally, 'as' is preferable to 'Class()' in ActionScript as it behaves more like casting in other languages.
I use it when I have an ArrayCollection of objects and need to enumerate through them, or use a selector function.
e.g.
var abc:mytype = mycollection.getItemAt(i) as mytype

argument name in the lua function call

I am looking for a more pleasant way to add an argument name while calling a function.
Something which is better than either of these
local ret = foo( --[[argNam1 =]] true)
local ret = foo( true ) -- first argument is argName1
I tried
local ret = foo( argNam1 = true)
but I got error
')' expected near '='
You could use named parameters, if that's what you want. Lua tables are good for imitating that behavior. So instead of passing all parameters separated by a comma, you pass a single table object; that has named keys.
If that is your foo() function:
local foo(parameters)
print(parameters.argNam1)
end
Then you could call it like: local ret = foo{argNam1 = true}
Or call it like this:
local arguments = {
argNam1 = true,
argNam2 = "foobar"
}
local ret = foo(arguments)