Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Nullable 1:1 connections #67

Merged
merged 1 commit into from
Mar 13, 2018
Merged

Conversation

Totktonada
Copy link
Member

@Totktonada Totktonada commented Mar 6, 2018

Fixes #44.

@Totktonada Totktonada added enhancement New feature or request prio1 labels Mar 6, 2018
@Totktonada Totktonada self-assigned this Mar 6, 2018
@Totktonada Totktonada force-pushed the gh-44-nullable-1-1-connections branch from eca0b2b to e9887a5 Compare March 7, 2018 01:12
@Totktonada Totktonada changed the title WIP: nullable 1:1 connections Nullable 1:1 connections Mar 7, 2018
@Totktonada
Copy link
Member Author

@Khatskevich @SudoBobo The PR is ready for review.

Copy link
Contributor

@Khatskevich Khatskevich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First phase, but not the last...

assert(c.type == '1:1' or c.type == '1:N',
'connection.type must be 1:1 or 1:N, got ' .. c.type)
assert(c.type == '1:1' or c.type == '1:1*' or c.type == '1:N',
'connection.type must be 1:1, 1:1* or 1:N, got ' .. c.type)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like * syntax. It looks like magic for the person who see it the first time

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional field (nullable=true) would also simplify your code. Because now 1:1 and 1:1* are generally the same, but you check both

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to be consistent with our extended avro-schema approach.

@@ -253,7 +253,7 @@ end
--- The function converts passed avro-schema to a GraphQL type.
---
--- @tparam table state for read state.accessor and previously filled
--- state.types (state.types are gql types)
--- state.nullable_collection_types (its are gql types)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -230,7 +230,7 @@ end
--- Convert each field of an avro-schema to a graphql type.
---
--- @tparam table state for read state.accessor and previously filled
--- state.types
--- state.nullable_collection_types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you rename it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally against common words to refer specific things. This field contains only collection types (and does not contain, say, nested records) and that types converted to nullable ones (because of lazy types evaluation, consider comments). So more specific name nullable_collection_types is fair term for that. Maybe collection_types_nullable is better, though.

assert(destination_type ~= nil,
('destination_type (named %s) must not be nil'):format(
c.destination_collection))

local c_args
if c.type == '1:1' then
destination_type = types.nonNull(
state.nullable_collection_types[c.destination_collection])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you do not reuse destination type?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make collection nonnull 2 times? I do not understand completely what would happen in this case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Fixed.
  2. I’m sure that collection types are nullable because it is how I save it.

@@ -405,7 +450,7 @@ gql_type = function(state, avro_schema, collection, collection_name)
avro_schema.name,
fields = fields,
})
return avro_t == 'enum' and types.nonNull(res) or res
return avro_t == 'record' and types.nonNull(res) or res
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be I am wrong, but I suppose that if the type is nullable or not should decide type user, but not type itself.
I suggest always return nullable types.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea, but it would be architectural change. It is smth that we can have in our minds to consider. Thanks!

end

results = results .. print_and_return(([[
+---------------------+
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is that?) Why do you print it? Moreover it is not printed in shard tests. Better to just leave it as a comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to print in shard tests. Will do. It was for convenient investigation of run of the test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider yaml module in tarantool:

third_party/lua-yaml/lyaml.cc

         } else if (strstr(str, "\n\n") != NULL) {
            /*  
             * Tarantool-specific: use literal style for string with empty lines.
             * Useful for tutorial().
             */
            style = YAML_LITERAL_SCALAR_STYLE;
         }   

I added two newlines in the begin of the string and got right output for the shard tests.

@@ -0,0 +1,398 @@
-- The example was inspired by [1]. Consider [2] for the problem description
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is up to you, but I do not like those teste. In my opinion we need to:

  1. Write common tests
  2. Check results in tests

Pros:

  1. To validate test results we do not need to read 3 result files
  2. The code you copy can contain small bugs, so, it should also be read 3 times
    It is just a waste of time!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I should work on reducing code size of the tests. Maybe I should consider 'common' test suite + tap13, but I want to: run local test as just file, don’t repeat the sime initialization / running steps, working shard module reloading. I’ll consider your pain at reading in the next PRs.

@Totktonada Totktonada force-pushed the gh-44-nullable-1-1-connections branch 2 times, most recently from 59e28ff to f79bdaf Compare March 7, 2018 13:36
Copy link
Contributor

@Khatskevich Khatskevich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I request some important changes.
See comments.

value

if value ~= nil then -- nil or box.NULL
are_all_parts_null = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this code should be moved outside of the closure (as a call to a function)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ll think about that before merge, but I’ll skip it now. Thanks for the point.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that similar effort was made by @SudoBobo in the scope of #8. I’m going to leave it as is for now. Feel free to file an issue re code refactoring if you want to track this.

local is_full_match_ok = are_all_parts_null or
are_all_parts_non_null
if not is_full_match_ok then -- avoid extra json.encode()
assert(is_full_match_ok,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete if, it is useless because your assert contains the same condition

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, read the comment for this if.

-- key parts
--
-- zero parts count considered as ok by this check
local is_full_match_ok = are_all_parts_null or
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like the extra variable with the strange name is_full_match_ok. It does not increase readability and should be used only once in the following assert, please, use just are_all_parts_null or are_all_parts_non_null instead (in assert).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I’ll use name ok. Don’t want to carry lines, it looks ugly here.

-- return the empty list.
if are_all_parts_null then
assert(c.type == '1:1*' or c.type == '1:N',
'only 1:1* or 1:N connections can have ' ..
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not split the user-visible output into lines (grep). We should follow this rule in the future too.
To maintain good code style, I propose to create a file with error messages.

Moreover, in this particular case, I believe you should provide extra information about the failed object. Because even after user sees this error, it is impossible to debug the case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed the line carrying in the case in context of tarantool code style and decided to force formal line lenght limit. So I’ll prefer to fit the limit, but I’ll try to split a message by meaningful parts.

extra info: TBD

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra info: added

end

-- check FULL match constraint before request of
-- destination object(s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Half of your comments are sentences with a dot at the end and start with a capital teller, and half of them are just text. I like the first option more. Let's follow the style?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My approach is the following. I use small letter in the begin and omit period at the end when the comment is one clause or like so (maybe even an expanded sentence, but only one). Several sentences started from capital letter and have period at the end.

Here we have several sentences, so I reformatted this into one multi-sentence comment (capital letter + period).


local function new_email(body)
return {
localpart = random_string(16):hex(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, do not use random functions for pest data. This field can not be used in test output because it is not consistent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initialized PRNG with a constant seed. You can use it in the output and it will be the same.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found that math.random() gives different numbers on different machines. Implemented simple PRNG in the test.

end)

-- FULL MATCH constraint: connection key parts must be all non-nulls or all
-- nulls
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, create 1 failing test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two failing tests here. Commented explicitly that they are fails.

@Totktonada Totktonada force-pushed the gh-44-nullable-1-1-connections branch 2 times, most recently from d7eab2c to 291cf7e Compare March 12, 2018 21:54
@Totktonada Totktonada force-pushed the gh-44-nullable-1-1-connections branch from 291cf7e to 13c5c7b Compare March 12, 2018 23:57
Copy link
Contributor

@Khatskevich Khatskevich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything is negotiated or fixed. ACK

@Totktonada Totktonada merged commit 8bc5331 into master Mar 13, 2018
@Totktonada Totktonada deleted the gh-44-nullable-1-1-connections branch March 13, 2018 21:07
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request prio1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants