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 }