Red.git | lib/Red/Cli/ | Table.rakumod
use Red::Utils;
use Red::Cli::Column;
use Red::Cli::Relationship;
unit class Red::Cli::Table;
has Str $.name;
has Str $.model-name = try { snake-to-camel-case $!name };
has @.columns;
has @.relationships;
has Bool $.exists = True;
submethod TWEAK(:@columns) {
for @columns -> $col {
$col.table = self;
with $col.references {
@!relationships.push: Red::Cli::Relationship.new: :id($col)
}
}
}
multi method model-definition($ where so *) { "unit model { $!model-name };\n" }
multi method model-definition($ where not *) { "model { $!model-name } \{" }
multi method model-end($ where so *) { "" }
multi method model-end($ where not *) { "\}" }
method to-code(Str :$schema-class, Bool :$no-relationships) {
my $unit = not $schema-class.defined;
qq:to/END/;
{ self.model-definition: $unit }
{ do for @!columns -> $col {
$col.to-code: :$schema-class
}.join("\n").indent: $unit ?? 0 !! 4 }
{ "\n" ~ do for @!relationships -> $rel {
$rel.to-code: :$schema-class
}.join("\n").indent: $unit ?? 0 !! 4 unless $no-relationships}
{ self.model-end: $unit }
END
}
method diff(::?CLASS $b) {
my @diffs;
if $!name ne $b.name {
@diffs.push: [ $!name, "+", "name", $b.name ];
@diffs.push: [ $!name, "-", "name", $!name ];
}
if @!columns != $b.columns {
@diffs.push: [ $!name, "+", "n-of-cols", $b.columns.elems ];
@diffs.push: [ $!name, "-", "n-of-cols", @!columns.elems ];
}
my @a = @!columns.sort: *.name;
my @b = $b.columns.sort: *.name;
while @a > 0 and @b > 0 {
if @a.head.name eq @b.head.name {
my $a = @a.shift;
my $b = @b.shift;
for $a.diff: $b -> @d {
@diffs.push: [ $!name, |@d ]
}
} elsif @b.head lt @a.head {
@diffs.push: [ $!name, "+", "col", @b.shift ];
} elsif @a.head lt @b.head {
@diffs.push: [ $!name, "-", "col", @a.shift ];
}
}
@diffs.push: [ $!name, "+", "col", $_ ] for @b;
@diffs.push: [ $!name, "-", "col", $_ ] for @a;
@diffs
}