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

add support of union connections, closes #8 #82

Merged
merged 7 commits into from
Mar 16, 2018
Merged

Conversation

SudoBobo
Copy link
Contributor

Add new type of connections - union connections, as they described in #8. With this connection type it is possible to represent a situation when entities in child table reference different parent tables. For example, let us have child table User and parent tables Basic and Premium. One user in User table may reference to a basic user info in Basic table, while another may reference to a premium info in Premium table. In GraphQL it is represented as Union type like this:

User {
   user_id: ID
   connection_field_name: Basic | Premium
}

@SudoBobo SudoBobo requested a review from Totktonada March 14, 2018 20:20
@SudoBobo SudoBobo self-assigned this Mar 14, 2018
Copy link
Member

@Totktonada Totktonada left a comment

Choose a reason for hiding this comment

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

I think the implementation can be simplified in several places, the proposals are added as comments. Let’s catch me for discussions if they are needed.

box.once('test_space_init_spaces', function()
box.schema.create_space('hero_collection')
box.space.hero_collection:create_index('hero_id_index',
{ type = 'tree', unique = true, parts = { U_USER_ID_FN, 'string' }}
Copy link
Member

Choose a reason for hiding this comment

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

Strictly speaking the field which number you marked via U_USER_ID_FN is not user_id. And the comment above user_collection fields is not relevant for hero/human/starship/hero_info. It is just small naming issue.

Side note: indent.

box.space._schema:delete('oncetest_space_init_spaces')
box.space.human_collection:drop()
box.space.starship_collection:drop()
box.space.hero_collection:drop()
Copy link
Member

Choose a reason for hiding this comment

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

Drop hero_info too?

Copy link
Member

Choose a reason for hiding this comment

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

You are deleted it, okay. The comment is not more actual.

{ "name": "episode", "type": "string"}
]
},
"hero_info": {
Copy link
Member

Choose a reason for hiding this comment

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

It seems you don’t use hero_info collection / connection. Is it needed, what do you think?


utils.show_trace(function()
local variables_1 = {hero_id = 'hero_id_1'}
local gql_query_1 = gql_wrapper:compile(query)
Copy link
Member

Choose a reason for hiding this comment

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

Just note: you can compile it once and use several times.

local gql_query_1 = gql_wrapper:compile(query)
local result = gql_query_1:execute(variables_1)
results = results .. print_and_return(
('RESULT\n%s'):format(yaml.encode(result)))
Copy link
Member

Choose a reason for hiding this comment

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

Consider using the following if you are interested (grep for the function and its use over the other tests):

results = results .. print_and_return(format_result(
    '1', query_1, variables_1, result))

Side note: indent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we create test/utils.lua to store functions like this?

Copy link
Member

Choose a reason for hiding this comment

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

Good idea.

local resulting_variant
for determinant, variant in pairs(determinant_to_variant) do
local is_match = true
for determinant_key, determinant_value in pairs(determinant) do
Copy link
Member

Choose a reason for hiding this comment

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

Can we reuse utils.is_subtable here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea

end
local objs = state.accessor:select(parent,
v.destination_collection, from,
object_args_instance, list_args_instance, extra)
Copy link
Member

Choose a reason for hiding this comment

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

Indent.

'on top of non-unique index ("%s")'):format(
c.name, index_name))
connection_indexes[c.destination_collection][c.name] =
set_connection_index(c, c.name, c.type, collection_name,
Copy link
Member

Choose a reason for hiding this comment

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

Indent.

connection_indexes[v.destination_collection] = {}
end
connection_indexes[v.destination_collection][c.name] =
set_connection_index(v, c.name, c.type, collection_name,
Copy link
Member

Choose a reason for hiding this comment

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

Indent.

if connection_indexes[v.destination_collection] == nil then
connection_indexes[v.destination_collection] = {}
end
connection_indexes[v.destination_collection][c.name] =
Copy link
Member

Choose a reason for hiding this comment

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

It always set index for the last variant (let’s expend your test on this case). There are two option I see to mitigate this problem:

  1. Pass fake 'single connections' instead of a union connection to accessor_general.
  2. Expand connection_indexes to have one more level of nesting (variant_num). Expand from parameter to have variant_num.

I think the patch should try consolidate main changes either in tarantool_graphql or accessor_general, otherwise we likely spread some abstractions across both modules instead of hide it in the one. Maybe the first option is better in the scope of this view. But 'fake single connection' can be considered as redundant new abstraction, so I don’t sure.

Are you understand the question I raise in this terms? My communication skills are not good within this domain.

Copy link
Contributor Author

@SudoBobo SudoBobo Mar 16, 2018

Choose a reason for hiding this comment

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

connection_indexes[v.destination_collection][c.name] = ... sets indexe for a destination collection, doesn't it? As a result we will have right index for each destination collection and that's what we want.

Copy link
Member

Choose a reason for hiding this comment

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

It seems that I missed that that is destination collection. There is an one problem, but it is not the regression. Consider A → C and B → C connections with the same names. Only last one will be saved in the connection_indexes structure and A → C connection can fail during execution.

There is one more problem, but it seems to be quite synthetic: variants to the same destination collection have the same problem.

@SudoBobo Can you file an issue on that, please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

@Totktonada Totktonada left a comment

Choose a reason for hiding this comment

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

LGTM.

@Totktonada Totktonada merged commit 7df24d9 into master Mar 16, 2018
@Totktonada Totktonada deleted the sb/union_clean_fix branch March 16, 2018 18:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants