def generate_schema_graph(orientdb_client: OrientDB) -> SchemaGraph: """Generate SchemaGraph from a pyorient client.""" schema_records = orientdb_client.command(ORIENTDB_SCHEMA_RECORDS_QUERY) schema_data = [x.oRecordData for x in schema_records] index_records = orientdb_client.command(ORIENTDB_INDEX_RECORDS_QUERY) index_query_data = [x.oRecordData for x in index_records] return get_orientdb_schema_graph(schema_data, index_query_data)
def compile_and_run_match_query( common_schema_info: CommonSchemaInfo, graphql_query: str, parameters: Dict[str, Any], orientdb_client: OrientDB, ) -> List[Dict[str, Any]]: """Compile and run a MATCH query against the supplied graph client.""" # MATCH code emitted by the compiler expects Decimals to be passed in as strings converted_parameters = { name: try_convert_decimal_to_string(value) for name, value in six.iteritems(parameters) } compilation_result = graphql_to_match(common_schema_info, graphql_query, converted_parameters) # Get results, adding None for optional columns with no matches query = compilation_result.query results = [] for row in orientdb_client.command(query): row_dict = row.oRecordData for output_name in compilation_result.output_metadata: if output_name not in row_dict: row_dict[output_name] = None results.append(row.oRecordData) return results
def execute_graphql( schema: GraphQLSchema, test_data: CommonTestData, client: OrientDB, sample_parameters: Dict[str, Any], ) -> FrozenSet[Tuple[FrozenSet[Tuple[str, Any]], int]]: """Compile GraphQL query to MATCH, execute it against the test_db, and return the results.""" schema_based_type_equivalence_hints: Dict[ Union[GraphQLInterfaceType, GraphQLObjectType], GraphQLUnionType ] = {} if test_data.type_equivalence_hints: # For test convenience, we accept the type equivalence hints in string form. # Here, we convert them to the required GraphQL types. for key, value in six.iteritems(test_data.type_equivalence_hints): key_type = schema.get_type(key) value_type = schema.get_type(value) if ( key_type and value_type and ( isinstance(key_type, GraphQLInterfaceType) or isinstance(key_type, GraphQLObjectType) ) and isinstance(value_type, GraphQLUnionType) ): schema_based_type_equivalence_hints[key_type] = value_type else: raise AssertionError( "Expected key_type to be of type GraphQLInterfaceType or GraphQLObject Type, " "but received {}; and value_type to be of type GraphQLUnionType, but " "received {}.".format(type(key_type), type(value_type)) ) common_schema_info = CommonSchemaInfo(schema, schema_based_type_equivalence_hints) result = graphql_to_match(common_schema_info, test_data.graphql_input, sample_parameters) # We need to preprocess the results to be agnostic of the returned order. # For this we perform the following steps # - convert lists (returned from @fold scopes) to tuples to make them hashable # - convert each row dict to a frozenset of its items # - create a Counter (multi-set) of the row frozensets # - convert the multi-set to a frozenset of its items row_dicts = [row.oRecordData for row in client.command(result.query)] if len(row_dicts) == 0: raise AssertionError("Zero records returned. Trivial snapshot not allowed.") row_dicts_using_tuples = [ { column_name: convert_decimals_to_strings( tuple(value) if isinstance(value, list) else value ) for column_name, value in row.items() } for row in row_dicts ] row_frozensets = [frozenset(row_dict.items()) for row_dict in row_dicts_using_tuples] rows_multiset = Counter(row_frozensets) row_counters_frozenset = frozenset(rows_multiset.items()) return row_counters_frozenset
def generate_schema( orientdb_client: OrientDB, class_to_field_type_overrides: Optional[ ClassToFieldTypeOverridesType] = None, hidden_classes: Optional[Set[str]] = None, ) -> Tuple[GraphQLSchema, TypeEquivalenceHintsType]: """Generate schema and type equivalence dict from a pyorient client.""" schema_records = orientdb_client.command(ORIENTDB_SCHEMA_RECORDS_QUERY) schema_data = [x.oRecordData for x in schema_records] return get_graphql_schema_from_orientdb_schema_data( schema_data, class_to_field_type_overrides, hidden_classes)