Red icon indicating copy to clipboard operation
Red copied to clipboard

map returning ResultSeq

Open FCO opened this issue 7 years ago • 8 comments

Should Person.all.map: { .posts } return a ResultSeq of ResultSeqs?

FCO avatar Aug 26 '18 16:08 FCO

What SQL should it generate?

FCO avatar Aug 26 '18 16:08 FCO

SELECT
   person.*,
   post.*
FROM
   person JOIN post ON(person.id = post.author_id)

FCO avatar Aug 26 '18 16:08 FCO

SELECT
   person.*,
   array_agg(post.*)
FROM
   person JOIN post ON(person.id = post.author_id)
GROUP BY
   person.id, person.name, ...

FCO avatar Aug 26 '18 16:08 FCO

SELECT
   array_agg(post.*)
FROM
   post
GROUP BY
   post.author_id

FCO avatar Aug 27 '18 20:08 FCO

For some reason I was thinking about this last night and came to the conclusion that actually it might be of least surprise to the user if it actually did something like :

SELECT
   post.*
FROM
   person JOIN post ON(person.id = post.author_id)

And returns a ResultSeq of Post.

Which of itself is fairly useless, until you have a grep before the map such as:

Person.^all.grep( ?*.active).map({ .posts})

And get:

SELECT
   post.*
FROM
   person JOIN post ON(person.id = post.author_id)
WHERE
   person.active

But just my ¢2

jonathanstowe avatar Feb 11 '19 19:02 jonathanstowe

O think that would be perfect for a .flatmap but I think it should return a Seq of Seqs...

Sent with GitHawk

FCO avatar Feb 12 '19 03:02 FCO

I had this problem today:

use Red;
my $*RED-DB = database "SQLite";
#my $*RED-DB = database "SQLite", :database</Users/fernando/test.db>;

model MongerPM { ... }

model Monger {
    has Int $!id             is serial;
    has Str $.name           is column;

    has MongerPM @.monger-pm is relationship{ .monger-id }

    method pms { @!monger-pm.map: *.pm }
}

model PMGroup is table<pm_group> {
    has Str $.city           is id;

    has MongerPM @!monger-pm is relationship{ .pm-id }

    method mongers { @!monger-pm.map: *.monger }
    method gist { "{ $!city }.PM" }
}

model MongerPM is table<monger_pm> {
    has Int $.monger-id  is referencing{ Monger.id };
    has Str $.pm-id      is referencing{ PMGroup.city };

    has Monger  $.monger is relationship{ .monger-id };
    has PMGroup $.pm     is relationship{ .pm-id     };
}

#my $*RED-DEBUG = True;
Monger.^create-table;
PMGroup.^create-table;
MongerPM.^create-table;

my $*RED-DEBUG = True;

my $pm        = PMGroup.^create: :city<Rio>;
my $monger    = Monger.^create: :name<Fernando>;
MongerPM.^create: :$monger, :$pm;

#.monger-pm>>.pm.say for Monger.^all
#for Monger.^all -> $monger {
#    for $monger.monger-pm.map: *.pm {
#        .say
#    }
#}

.pms.say for Monger.^all

i think relationships of model type objects should continue returning the model, but it could mixin a role that would store what relationship it was, so, on translate it could use that...

multi method translate(Red::AST::Value $_ where .type ~~ Red::Model, $context?) {
    die "NYI: map returning a relationship";
}

FCO avatar Feb 24 '19 00:02 FCO

Maybe we could use the same approach we did in #417 here.

FCO avatar Jan 10 '23 22:01 FCO