use Red::Driver::Cache; use X::Red::Exceptions; use Red::AST; use Red::AST::Unary; use Red::AST::Select; use Red::AST::Infix; use Red::AST::Value; use Red::AST::LastInsertedRow; unit role Red::Driver::CacheWithStrKey does Red::Driver::Cache; method get-from-cache(Str) { ... } method set-on-cache(Str, @) { ... } multi method get-from-cache(Red::AST $ast) { CATCH { default { .say } } my Str $key = self.translate-key: $ast; self.get-from-cache: $key, :$ast } multi method set-on-cache(Red::AST $ast, @data) { my Str $key = self.translate-key: $ast; self.set-on-cache: $key, @data, :$ast } multi method translate-key(Red::AST::Cast $_, $context?) { "{ self.translate-key: .value }::{ .type }" } multi method translate-key(Red::AST::LastInsertedRow $_, $context?) { X::Red::Driver::Cache::DoNotCache.new.throw } multi method translate-key(Red::Column $_, $context?) { (.computation // $_).gist.subst: /\s+/, "_", :g } multi method translate-key(Red::Model:U $_, "table-list") { .^table } multi method translate-key(Red::Model:U $_, "of") { .^columns>>.column.map({ self.translate-key: $_, "of" }).join: "|" } multi method translate-key(Red::AST::Infix $_, $context) { "{ self.translate-key: .left, $context }_{ .op }_{ self.translate-key: .right, $context }" } multi method translate-key(Red::AST::Value $_, $context) { .value.Str } multi method translate-key(Red::AST::Select $_, $context?) { ( "CACHED_SELECT", self.translate-key(.of, "of"), "FROM", .tables.grep({ not .?no-table }).unique.map({ self.translate-key: $_, "table-list" }).join("|"), (|( "WHERE", self.translate-key($_, "filter"), ) with .filter), (|( "ORDER_BY", .order.map({ self.translate-key: $_, "order" }).join: "|" ) if .order), |( "LIMIT", .limit if .limit), |( "OFFSET", .offset if .offset), ).join: ":" }