mkql_simple_file.cpp 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include "mkql_simple_file.h"
  2. #include <yql/essentials/core/yql_user_data_storage.h>
  3. #include <yql/essentials/minikql/mkql_program_builder.h>
  4. #include <yql/essentials/minikql/mkql_node_cast.h>
  5. #include <util/stream/file.h>
  6. namespace NYql {
  7. using namespace NKikimr;
  8. using namespace NKikimr::NMiniKQL;
  9. TSimpleFileTransformProvider::TSimpleFileTransformProvider(const IFunctionRegistry* functionRegistry,
  10. const TUserDataTable& userDataBlocks)
  11. : FunctionRegistry_(functionRegistry)
  12. , UserDataBlocks_(userDataBlocks)
  13. {}
  14. TCallableVisitFunc TSimpleFileTransformProvider::operator()(TInternName name) {
  15. if (name == "FilePath") {
  16. return [&](NMiniKQL::TCallable& callable, const TTypeEnvironment& env) {
  17. MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arguments");
  18. const TString name(AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().AsStringRef());
  19. auto block = TUserDataStorage::FindUserDataBlock(UserDataBlocks_, name);
  20. MKQL_ENSURE(block, "File not found: " << name);
  21. MKQL_ENSURE(block->Type == EUserDataType::PATH || block->FrozenFile, "File is not frozen, name: "
  22. << name << ", block type: " << block->Type);
  23. return TProgramBuilder(env, *FunctionRegistry_).NewDataLiteral<NUdf::EDataSlot::String>(
  24. block->Type == EUserDataType::PATH ? block->Data : block->FrozenFile->GetPath().GetPath()
  25. );
  26. };
  27. }
  28. if (name == "FolderPath") {
  29. return [&](NMiniKQL::TCallable& callable, const TTypeEnvironment& env) {
  30. MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arguments");
  31. const TString name(AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().AsStringRef());
  32. auto folderName = TUserDataStorage::MakeFolderName(name);
  33. TMaybe<TString> folderPath;
  34. for (const auto& x : UserDataBlocks_) {
  35. if (!x.first.Alias().StartsWith(folderName)) {
  36. continue;
  37. }
  38. MKQL_ENSURE(x.second.Type == EUserDataType::PATH, "FolderPath not supported for non-file data block, name: "
  39. << x.first.Alias() << ", block type: " << x.second.Type);
  40. auto newFolderPath = x.second.Data.substr(0, x.second.Data.size() - (x.first.Alias().size() - folderName.size()));
  41. if (!folderPath) {
  42. folderPath = newFolderPath;
  43. } else {
  44. MKQL_ENSURE(*folderPath == newFolderPath, "File " << x.second.Data << " is out of directory " << *folderPath);
  45. }
  46. }
  47. return TProgramBuilder(env, *FunctionRegistry_).NewDataLiteral<NUdf::EDataSlot::String>(*folderPath);
  48. };
  49. }
  50. if (name == "FileContent") {
  51. return [&](NMiniKQL::TCallable& callable, const TTypeEnvironment& env) {
  52. MKQL_ENSURE(callable.GetInputsCount() == 1, "Expected 1 arguments");
  53. const TString name(AS_VALUE(TDataLiteral, callable.GetInput(0))->AsValue().AsStringRef());
  54. auto block = TUserDataStorage::FindUserDataBlock(UserDataBlocks_, name);
  55. MKQL_ENSURE(block, "File not found: " << name);
  56. const TProgramBuilder pgmBuilder(env, *FunctionRegistry_);
  57. if (block->Type == EUserDataType::PATH) {
  58. auto content = TFileInput(block->Data).ReadAll();
  59. return pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(content);
  60. }
  61. else if (block->Type == EUserDataType::RAW_INLINE_DATA) {
  62. return pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(block->Data);
  63. }
  64. else if (block->FrozenFile && block->Type == EUserDataType::URL) {
  65. auto content = TFileInput(block->FrozenFile->GetPath().GetPath()).ReadAll();
  66. return pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>(content);
  67. } else {
  68. MKQL_ENSURE(false, "Unsupported block type");
  69. }
  70. };
  71. }
  72. return TCallableVisitFunc();
  73. }
  74. } // NYql