import os from dataclasses import dataclass from typing import Iterable from dbt.contracts.graph.manifest import SourceFile from dbt.contracts.graph.parsed import ParsedRPCNode, ParsedMacro from dbt.contracts.graph.unparsed import UnparsedMacro from dbt.exceptions import InternalException from dbt.node_types import NodeType from dbt.parser.base import SimpleSQLParser from dbt.parser.macros import MacroParser from dbt.parser.search import FileBlock @dataclass class RPCBlock(FileBlock): rpc_name: str @property def name(self): return self.rpc_name class RPCCallParser(SimpleSQLParser[ParsedRPCNode]): def parse_from_dict(self, dct, validate=True) -> ParsedRPCNode: if validate: ParsedRPCNode.validate(dct) return ParsedRPCNode.from_dict(dct) @property def resource_type(self) -> NodeType: return NodeType.RPCCall def get_compiled_path(cls, block: FileBlock): # we do it this way to make mypy happy if not isinstance(block, RPCBlock): raise InternalException( 'While parsing RPC calls, got an actual file block instead of ' 'an RPC block: {}'.format(block) ) return os.path.join('rpc', block.name) def parse_remote(self, sql: str, name: str) -> ParsedRPCNode: source_file = SourceFile.remote(sql, self.project.project_name) contents = RPCBlock(rpc_name=name, file=source_file) return self.parse_node(contents) class RPCMacroParser(MacroParser): def parse_remote(self, contents) -> Iterable[ParsedMacro]: base = UnparsedMacro( path='from remote system', original_file_path='from remote system', package_name=self.project.project_name, raw_sql=contents, root_path=self.project.project_root, resource_type=NodeType.Macro, ) for node in self.parse_unparsed_macros(base): yield node