v icon indicating copy to clipboard operation
v copied to clipboard

parser: V ORM returns an array for non-count queries

Open walkingdevel opened this issue 2 years ago • 11 comments

This is the first PR from a series of breaking changes for V ORM, which makes it more consistent in working with types. Before this PR, V ORM didn't allow us to check a returned object from select for existence. Everything we could do is compare struct id with 0. It gave no guarantees and required the id field. Now, V ORM always returns an array for non-count queries. And you just can check the length of the result. If it is 0, select didn't return anything.

Example:

users := sql db {
	select from User
}

no_users := users.len == 0

walkingdevel avatar Mar 20 '23 18:03 walkingdevel

Wouldn't it make more sense to return an Option type, so it would either be a valid array or none?

JalonSolov avatar Mar 20 '23 18:03 JalonSolov

@JalonSolov, In the next PR, I'll add the Result for all V ORM queries.

walkingdevel avatar Mar 20 '23 18:03 walkingdevel

Because the result can contain an error from a database or something else which we should process.

walkingdevel avatar Mar 20 '23 18:03 walkingdevel

Because the result can contain an error from a database or something else which we should process.

This change is a bit sad, but it is what make more sense, already we can not return none or error in the same function.

enghitalo avatar Mar 20 '23 19:03 enghitalo

That's why I was against breaking the previous Result into Result + Option, but I was outvoted.

It is simple enough to return error('No results') and check for that specifically.

JalonSolov avatar Mar 20 '23 20:03 JalonSolov

That's why I was against breaking the previous Result into Result + Option, but I was outvoted.

It is simple enough to return error('No results') and check for that specifically.

IMHO, I, also, think that error('No results') can work better. But I also, think that we need to discuss a pattern to solve this kind of problem. I feel that this PR will solve a important problem creating another one.

enghitalo avatar Mar 21 '23 02:03 enghitalo

This problem existed before my PR, so I think I don't create another one. I just want to make ORM better and safer.

walkingdevel avatar Mar 21 '23 08:03 walkingdevel

It is simple enough to return error('No results') and check for that specifically.

No, it is not simple, and creates more problems on several levels.

SQL returns result sets, not single results, and these sets can be empty sets. That is not a problem/error, and should not be treated as such.

SQL queries however can have syntax errors, or they can fail because of runtime/DB changes (the connection was dropped during the execution of the query, the table could have its schema changed, so some columns may be now missing, or it could be dropped entirely etc).

-> The logical choice for the general return values of the ORM queries, is ![]Row, not a ?!SumtypeOfValueOrArrayOfValues.

With these changes to the ORM, the no result situation is just an empty array, the errors are just V errors, and the multiple results situation is just []Row .

spytheman avatar Mar 21 '23 09:03 spytheman

But I also, think that we need to discuss a pattern to solve this kind of problem. I feel that this PR will solve a important problem creating another one.

That discussion had been had many times already. No good solution, better than ![]Row that handles all situations was found. If you think you have one, please first think through all the edge cases, then present your solution in the V Discord server, or as a PR to the V's RFC repo here: https://github.com/vlang/rfcs/pulls .

spytheman avatar Mar 21 '23 09:03 spytheman

It is simple enough to return error('No results') and check for that specifically.

No, it is not simple, and creates more problems on several levels.

Umm... then you say

-> The logical choice for the general return values of the ORM queries, is ![]Row, not a ?!SumtypeOfValueOrArrayOfValues.

... which is basically the same as what I said, only more detailed.

If it is declared as a Result type, you can return error('No results'), which can be checked explicitly in the or block to tell if it was a problem of nothing matching the query vs an syntax/connection/whatever error.

JalonSolov avatar Mar 21 '23 11:03 JalonSolov

error('No results') != [] , that is the difference.

0 results is NOT an error. It is a valid result set.

spytheman avatar Mar 21 '23 12:03 spytheman