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

[WIP] Sb/avro arr #48

Closed
wants to merge 29 commits into from
Closed

[WIP] Sb/avro arr #48

wants to merge 29 commits into from

Conversation

SudoBobo
Copy link
Contributor

@SudoBobo SudoBobo commented Feb 21, 2018

closes #4

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.

Style comments, opinions re implementation approaches.

assert(gql_class.ofType ~= nil, 'gql_class.ofType must not be nil')
return gql_class.ofType
end
local nullable = utils.nullable
Copy link
Member

Choose a reason for hiding this comment

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

utils.lua is for auxiliary functions that do not contain domain-specific abstractions or logic. We work with graphql-lua types in core/*.lua and tarantool_graphql.lua. It is better to keep these objects within these files (or create new modules working within such terms), but don't mix abstraction layers. In other words, I propose to give back this function to this module. You can create graphql_utils.lua alternatively, but I don't think we have enough helpers to charge it.

@@ -96,15 +95,25 @@ local function convert_scalar_type(avro_schema, opts)
elseif avro_t == 'string*' then
return types.string
end

if opts.is_items_type then
Copy link
Member

Choose a reason for hiding this comment

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

// This is not more actual because I proposed to remove this option, but I kept this comment here to give you more on our conventions within the project.

Please, keep consistency with asserts and default values for options within the 'opts' parameter. Consider 'raise' as the example. More specific: add the local variable with a default value (or false), add assert for a type of this option. This is more about readability, then about runtime checks, because such function preamble give a developer information re function contract.


if opts.is_items_type then
error('avro array items must have know scalar type, not: ' ..
json.encode(avro_schema))
Copy link
Member

Choose a reason for hiding this comment

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

We use 4 spaces as indent.

@@ -96,15 +95,25 @@ local function convert_scalar_type(avro_schema, opts)
elseif avro_t == 'string*' then
return types.string
end

if opts.is_items_type then
error('avro array items must have know scalar type, not: ' ..
Copy link
Member

Choose a reason for hiding this comment

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

A user must have info to distinguish not-implemented-yet errors from its mistakes in configuration options (like avro-schemas). Proposed wording: "only scalars are supported as array items for now".

end

Copy link
Member

Choose a reason for hiding this comment

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

We don't use python-style double empty lines (moreover, here they are within a function, so don't fit PEP8 too). Consider our lua style guidelines: https://tarantool.org/en/doc/1.7/dev_guide/lua_style_guide.html

@@ -414,6 +497,8 @@ local function parse_cfg(cfg)
return state
end

--- The function checks if given query has an appropriate type 'query'
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 the function does the other action: it checks that one and only one GraphQL operation (query/mutation/subscription) is defined in the AST. That just the minimum check that we got an query AST and not mistakely some other value.

@@ -414,6 +497,8 @@ local function parse_cfg(cfg)
return state
end

--- The function checks if given query has an appropriate type 'query'
--- (mutations are not supported yet).
Copy link
Member

Choose a reason for hiding this comment

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

That note is unrelated to the function. It will doing what it doing despite types of GraphQL operations.

@@ -442,6 +529,12 @@ local function gql_execute(qstate, variables)
operation_name)
end

--- The function parses a raw query string, validate the resulting query
Copy link
Member

Choose a reason for hiding this comment

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

  1. The term 'raw' is a bit confusing, I think. Just 'a query string'.
  2. 'Validate the resulting query'. Too common. Make it specific by adding 'against the GraphQL scheme.
  3. 'Make it ready for execution'. Too common. You can say 'provides an object with the function to execute the query with specific variables values).

--- The function parses a raw query string, validate the resulting query
--- and make it ready for execution.
---
--- @tparam table state current state of graphql-lib, including
Copy link
Member

Choose a reason for hiding this comment

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

We don't used the term 'graphql-lib' before.

---
--- @tparam table state current state of graphql-lib, including
--- schemas, collections and accessor
--- @tparam string query raw query string
Copy link
Member

Choose a reason for hiding this comment

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

Proposed to omit the word 'raw'.

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.

Some style comments.

@@ -79,7 +87,7 @@ local function convert_scalar_type(avro_schema, opts)
assert(type(opts) == 'table', 'opts must be nil or table, got ' ..
type(opts))
local raise = opts.raise or false
assert(type(opts.raise) == 'boolean', 'opts.raise must be boolean, got ' ..
assert(type(raise) == 'boolean', 'opts.raise must be boolean, got ' ..
type(opts.raise))
Copy link
Member

Choose a reason for hiding this comment

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

Replace opts.raise with raise here too for consistency.

if raise then
error('unrecognized avro-schema scalar type: ' ..
json.encode(avro_schema))
json.encode(avro_schema))
Copy link
Member

Choose a reason for hiding this comment

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

Ping?

--- An error will be raised if avro_schema type is 'record'
--- and its' fields are not scalar type because currently
--- triple nesting level (record with record as a field - ok,
--- record with record wich has inside another level - not ok)
Copy link
Member

Choose a reason for hiding this comment

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

wich → which

@@ -149,44 +166,69 @@ local function gql_argument_type(state, avro_schema)
end
end


Copy link
Member

Choose a reason for hiding this comment

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

Extra empty line.

end
return args
end

--- Convert each field of an avro-schema to a graphql type and corresponding
--- argument for an upper graphql type.
--- Recursively convert each field of an avro-schema to a graphql type and
Copy link
Member

Choose a reason for hiding this comment

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

Ping?

function array_testdata.get_test_metadata()

local schemas = json.decode([[{
"user": {
Copy link
Member

Choose a reason for hiding this comment

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

Need one more indent level.

{ "name": "user_id", "type": "string" },
{ "name": "favorite_food", "type": {"type": "array", "items": "string"} }
]
}
Copy link
Member

Choose a reason for hiding this comment

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

Here indent is broken too.

box.once('test_space_init_spaces', function()
box.schema.create_space('user_collection')
box.space.user_collection:create_index('user_id_index',
{ type = 'tree', unique = true, parts = {
Copy link
Member

Choose a reason for hiding this comment

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

Minor comment. I’m a bit against such style of curly circles / indent. If the line carry, then do not start it on the same line as open curly bracket.

end

function array_testdata.run_queries(gql_wrapper)

Copy link
Member

Choose a reason for hiding this comment

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

Redundant empty line after the function header.

}
]]

--assert(false, 'err')
Copy link
Member

Choose a reason for hiding this comment

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

Forgotten debug, I guess.

@Totktonada
Copy link
Member

graphql/utils.lua 100644 → 100755

The module is not desined to be run as executable. I think it is better to don’t have executable bit set on such modules. @SudoBobo, please, revert (chmod a-x graphql/utils.lua) the change.

@Totktonada Totktonada added enhancement New feature or request prio1 labels Feb 27, 2018
user_balances {
value
}
customer_balances
Copy link
Member

Choose a reason for hiding this comment

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

Should it work when you don’t choose any fields inside?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, because it is Map and our Map is a scalar-based type. In GraphQL scalar-based types don't have any inner fields

Copy link
Member

Choose a reason for hiding this comment

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

Okay, I got it. Thanks! I think we should mention record vs map differences in README.md or somewhere like.

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.

README comments.

README.md Outdated
While Object is a GraphQL
built-in type, Map is a scalar-based type. In case of Object-based type
all key-value pairs are set during type definition and values may have different
arbitrary types.
Copy link
Member

Choose a reason for hiding this comment

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

different arbitrary types → different types as defined in the schema; what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Your variant is more specific.

README.md Outdated
arbitrary types.

In contrast, all values of Map-based type must have the same
type and specific key-value pairs are not set during type definition.
Copy link
Member

Choose a reason for hiding this comment

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

specific key-value pairs are not set during type definition → set of valid keys is not defined in the schema, any key-value pair is valid despite name of the key while value has schema-determined type; what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

set of valid keys is not defined in the schema, any key-value pair is valid despite name of the key while value has schema-determined type (which is the same among all values in the map) ?

Copy link
Member

Choose a reason for hiding this comment

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

Ok.

README.md Outdated
type and specific key-value pairs are not set during type definition.

Map-based types should be queried as a scalar type, not as an object type
(because map's keys are not part of the schema)
Copy link
Member

Choose a reason for hiding this comment

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

Period at the end.

README.md Outdated
In contrast, all values of Map-based type must have the same
type and specific key-value pairs are not set during type definition.

Map-based types should be queried as a scalar type, not as an object type
Copy link
Member

Choose a reason for hiding this comment

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

  • as a scalar type → as a scalar type (strictly w/o set of nested fields);
  • as an object type → as an object type (strictly with set of nested fields).

--require('pl.pretty').dump(object)
--print('print from default resolver in 86')
--require('pl.pretty').dump(info.fieldASTs[1].name.value)
--require('pl.pretty').dump(object[info.fieldASTs[1].name.value])
Copy link
Member

Choose a reason for hiding this comment

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

Forgotten debug.

@@ -148,6 +155,25 @@ end

local evaluateSelections

--- check if given object is flat and have only scalars
Copy link
Member

Choose a reason for hiding this comment

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

If you want to add ldoc comment, then use it's convention: start short function description with a capital letter and end it with a period. Otherwise, use a regular comment (--).

'arbitrary but same among all values type',
serialize = function(value) return value end,
parseValue = function(value)return value end,
-- node == ast
Copy link
Member

Choose a reason for hiding this comment

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

I think you should comment what is purpose of this line of code or remove the line completely.

return nil
end

--- Non-recursive version of the @{gql_type} function that returns
--- InputObject instead of Object.
--- An error will be raised if avro_schema type is 'record'
--- and its' fields are not scalar type because currently
--- triple nesting level (record with record as a field - ok,
Copy link
Member

Choose a reason for hiding this comment

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

Currently triple nesting level... what? Is not supported?

@@ -197,6 +251,10 @@ end
--- automatically generate corresponding decucible fields.
--- 2. The collection name will be used as the resulting graphql type name
--- instead of the avro-schema name.
---
--- XXX As it is not clear now what to do with complex types inside arrays
--- (just pass to results or allow to use filters), only scalar arrays
Copy link
Member

Choose a reason for hiding this comment

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

You can mention here that map is included into scalar types for now.

'got %s (avro_schema %s)'):format(type(avro_schema.values),
json.encode(avro_schema)))

gql_type(state, avro_schema.values)
Copy link
Member

Choose a reason for hiding this comment

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

Do you want to comment that it is for asserts? Just to validate the values format against avro-schema format (

@Totktonada Totktonada deleted the sb/avro_arr branch February 28, 2018 21:31
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.

Support for avro array / map
2 participants