Red icon indicating copy to clipboard operation
Red copied to clipboard

Deal with multi level package names in models

Open jonathanstowe opened this issue 7 years ago • 10 comments

If the model type name doesn't resolve as a single level then it makes a mess of creating the table name:

use Red;
  

module Bar {
    model Foo {
        has Int $.id    is serial;
        has Str $.name  is column;
    }
}

my $*RED-DEBUG          = $_ with %*ENV<RED_DEBUG>;
my $*RED-DEBUG-RESPONSE = $_ with %*ENV<RED_DEBUG_RESPONSE>;
my $*RED-DB             = database "SQLite", |(:database($_) with %*ENV<RED_DATABASE>);


Bar::Foo.^create-table;

Gives rise to:

'bar::foo' is an invalid table name for driver Red::Driver::SQLite
  in method create-table at /home/jonathan/devel/perl6/3rdparty-modules/Red/lib/MetamodelX/Red/Model.pm6 (MetamodelX::Red::Model) line 176
  in block <unit> at yy line 16

Obviously this can be remedied by supplying the is table trait to the model, but organizing a set of classes within an outer module is a sufficiently common practice that maybe it should be handled a bit more nicely. The easiest would be just to use the "local" part of the name for the table by default, alternatively simply replacing the invalid characters with an '_'. A more refined solution would be, where the DB backend supports it, to allow the namespace qualifying of the tables perhaps even supplying an is namespace trait for the surrounding package. For Pg this would translate to the schema and perhaps for SQLite as an "attached database" (https://www.sqlite.org/lang_naming.html, which has its own difficulties.)

Again, as there is a sensible workaround I wouldn't give it too high a priority, but just something to think about it.

jonathanstowe avatar Jan 01 '19 15:01 jonathanstowe

Yes, good idea!

FCO avatar Jan 01 '19 21:01 FCO

As I got into this issue too, so, got a note to take into account... While mapping into a schema is an interesting idea it has a couple of issues. Firstly, schemas cannot be nested in Postgres (know nothing about other DBs). If an app with a complex structure defines a Models::Data::Table, we won't be able to create models.data.table. While this could be overrules by replacing :: with double underscores __ in containing module name (models__data schema) there is another potential issue of Postgres limiting names to 63 characters. Not sure how unlikely would it be to hit this limit. But considering that data structures (which models are) are usually been hidden deep inside code structure, the risk is not overly low. Perhaps a driver must take this into consideration and issue a warning if a name happens to be too long.

vrurg avatar May 06 '19 01:05 vrurg

Update for a long-pending issue. With :api<2> changing the syntax of referencing and relationship traits making :model required, it would make sense to provide support for passing model type object to :model:

model M1 { ... }
model M2 {
   has $.m1 is relationship(*.id, :model(M1));
}

And, yes, I did bump into this problem again a few minutes ago. :)

vrurg avatar Jan 12 '20 01:01 vrurg

Isn’t it being supported?

Sent with GitHawk

FCO avatar Jan 12 '20 03:01 FCO

No. referencing trait explicitly declares $model to be a Str.

vrurg avatar Jan 12 '20 03:01 vrurg

Worse than that, as I'm currently trying to investigate, Red::Attr::Relationship accepts $model as Str only.

vrurg avatar Jan 12 '20 03:01 vrurg

We have to fix it... :)

Sent with GitHawk

FCO avatar Jan 12 '20 04:01 FCO

I've forgotten mentioning it here, but I've created 2 new experimental features that modifies this behaviour:

  • shortname that makes Red use only the shortname of the module to generate the table name
  • formats that allows you to set functions that will be used to generate the tables and columns names. eg:
my &*RED-TABLE-FORMATER  = -> $name { "RED_TABLE_$name" }
my &*RED-COLUMN-FORMATER = -> $name { "`$name`" }

(https://fco.github.io/Red/tutorials/experimental.html)

FCO avatar Feb 14 '21 11:02 FCO

It's probably too late but FORMATER is spelled wrong :-D

jonathanstowe avatar Feb 15 '21 10:02 jonathanstowe

Is it fixed now?

FCO avatar Feb 16 '21 23:02 FCO