RaCoCo result: Red::Driver::SQLite::SchemaReader

# Red::Driver::SQLite::SchemaReader 8.1%

    use Red::SchemaReader;
    use Red::Driver::SQLite::SQLiteMaster;

    #| An internal class to read SQLite schemes.
    unit class Red::Driver::SQLite::SchemaReader;
    also does Red::SchemaReader;

    method sqlite-master { Red::Driver::SQLite::SQLiteMaster }

    #use Grammar::Tracer::Compact;
    grammar SQL::CreateTable {
        rule  TOP                      { :i <create-table>+ %% ";" }
        rule  create-table             { :i CREATE TABLE <table-name=.name> '(' ~ ')' <column>+ %% [ "," ] }
        token name                     { :i \w+ }
        rule  type                     { :i <name>["(" ~ ")" \d+]? }
        rule  column                   { :i <column-name=.name> <type> <modifier>? <index-mod>? <auto-increment>? }
        rule  auto-increment           { :i "AUTOINCREMENT" }
        proto rule modifier            {*}
        multi rule modifier:<null>     { :i NULL }
        multi rule modifier:<not-null> { :i NOT NULL }
        proto rule index-mod           {*}
        multi rule index-mod:<pk>      { :i PRIMARY KEY }
        multi rule index-mod:<fk>      { :i REFERENCES <table-name=.name> '(' ~ ')' <column-name=.name> }
        multi rule index-mod:<unique>  { :i UNIQUE }
        proto rule index               {*}
        multi rule index:<pk>          { :i PRIMARY KEY '(' ~ ')' <column-name=.name>+ % "," }
        multi rule index:<fk>          { :i FOREIGN KEY <local-column-name=.name> REFERENCES '(' ~ ')' <column-name=.name>+ % "," }
        multi rule index:<unique>      { :i UNIQUE '(' ~ ')' <column-name=.name>+ % "," }
    }

    class SQL::CreateTable::Action {
        use Red::Cli::Table;
        use Red::Cli::Column;
        method TOP($/)                 { make $<create-table>».made }
        method create-table($/)        { make Red::Cli::Table.new: name => $<table-name>.made, columns => $<column>».made }
        method name($/)                { make ~$/ }
        method type($/)                { make $/.Str.trim}
        method column($/)              {
            make Red::Cli::Column.new(
                $<column-name>.made,
                $<type>.made,
                ($<modifier>.made // True),
                |$<index-mod>.made<pk unique references>
            )
        }
        method auto-increment          { make ( :auto-increment ) }
        method modifier:<null>($/)     { make ( :nullable ) }
        method modifier:<not-null>($/) { make ( :!nullable ) }
        method index-mod:<pk>($/)      { make ( :pk ) }
        method index-mod:<fk>($/)      { make ( :references( %( table => $<table-name>.made, column => $<column-name>.made ) ) ) }
        method index-mod:<unique>($/)  { make ( :unique ) }
        method index:<pk>($/)          { ... }
        method index:<fk>($/)          { ... }
        method index:<unique>($/)      { ... }
    }

    method tables-names       { self.sqlite-master.tables.map: *.name }
    method indexes-of($table) { self.sqlite-master.find-table($table).indexes }
    method table-definition($table) {
        my $sql = self.sqlite-master.find-table($table).sql;
        my $list = self.table-definition-from-create-table($sql);
        return unless $list;
        $list.head
    }
    multi method table-definition-from-create-table(Str:D $sql) {
        SQL::CreateTable.parse($sql, :actions(SQL::CreateTable::Action)).made;
    }

    multi method table-definition-from-create-table(Any:U) {
        Red::Cli::Table.new
    }