### ----------------------------------------------------
### -- UpRooted
### -- Licenses: Artistic-2.0
### -- Authors: Paweł bbkr Pabian
### -- File: t/44-writer-postgresql.rakutest
### ----------------------------------------------------
use lib 'lib';
use lib 't/lib';

use Test;

use DBITest;
use UpRooted::Schema;
use UpRooted::Table;
use UpRooted::Column;
use UpRooted::Relation;
use UpRooted::Tree;
use UpRooted::Reader;
use UpRooted::Writer::PostgreSQL;

my $connection = connect( 'postgresql' );
load( $connection, 'postgresql', 'cleanup.sql' );
load( $connection, 'postgresql', 'schema.sql' );

plan 3;

my $complex-row;
class UpRooted::Reader::Dummy does UpRooted::Reader {

    method !read-path ( $path, %conditions ) {
        
        given $path.leaf-table.name {
            when 't1' {
                take $complex-row = [
                    1, 'a', '😀😔', '😀😔', -1, 1, 9223372036854775807, 1.1, -0.3e0, 0.3e0, Buf.new( 0x00 ), Bool::True, Array[Int].new( 1, 2, 3 )
                ]
            }
            when 't2' {
                take [ 1, 1 ];
                take [ 2, 1 ];
            }
            when 't4' {
                take [ 1, 1, 1 ];
                take [ 2, Any:U, 1 ];
            }
        }
    }
}

# match schema.sql definitions
my $statement = $connection.execute( 'SELECT CURRENT_SCHEMA()' );
my $schema-name = $statement.row( )[ 0 ];
$statement.dispose( );
my $schema = UpRooted::Schema.new( name => $schema-name );
UpRooted::Table.new( :$schema, name => 't1' );
UpRooted::Column.new( table => $schema.table( 't1' ), name => 'id', :!is-nullable, type => 'bigint' );
my @column_types = 'char', 'varchar', 'text', 'smallint', 'int', 'bigint', 'numeric', 'real', 'double precision', 'bytea', 'boolean', 'array';
for @column_types.kv -> $index, $type {
    my $name = sprintf 'c_%.2d', $index + 1;
    UpRooted::Column.new( table => $schema.table( 't1' ), :$name, :is-nullable, :$type );
}
UpRooted::Table.new( :$schema, name => 't2' );
UpRooted::Column.new( table => $schema.table( 't2' ), name => 'id', :!is-nullable, type => 'bigint' );
UpRooted::Column.new( table => $schema.table( 't2' ), name => 't1_id', :!is-nullable, type => 'bigint' );
UpRooted::Table.new( :$schema, name => 't4' );
UpRooted::Column.new( table => $schema.table( 't4' ), name => 'id', :!is-nullable, type => 'bigint' );
UpRooted::Column.new( table => $schema.table( 't4' ), name => 't1_id', :is-nullable, type => 'bigint' );
UpRooted::Column.new( table => $schema.table( 't4' ), name => 't2_id', :!is-nullable, type => 'bigint' );
UpRooted::Relation.new(
    parent-columns => $schema.table( 't1' ).columns( 'id' ),
    child-columns => $schema.table( 't2' ).columns( 't1_id' ),
    name => 'r1'
);
UpRooted::Relation.new(
    parent-columns => $schema.table( 't1' ).columns( 'id' ),
    child-columns => $schema.table( 't4' ).columns( 't1_id' ),
    name => 'r2'
);
UpRooted::Relation.new(
    parent-columns => $schema.table( 't2' ).columns( 'id' ),
    child-columns => $schema.table( 't4' ).columns( 't2_id' ),
    name => 'r3'
);

my $tree = UpRooted::Tree.new( root-table => $schema.table( 't1' ) );
my $reader = UpRooted::Reader::Dummy.new( :$tree );
my $writer = UpRooted::Writer::PostgreSQL.new( :$connection );

$writer.write( $reader );

is-deeply $connection.execute( 'SELECT * FROM "t1"' ).allrows( )[ 0 ], $complex-row, 'Root row from t1 UpRooted::Table';
is-deeply $connection.execute( 'SELECT * FROM "t2" ORDER BY "id"' ).allrows( ), ( [ 1, 1 ], [ 2, 1 ] ), 'Leaf rows from t2 UpRooted::Table';
is-deeply $connection.execute( 'SELECT * FROM "t4" ORDER BY "id"' ).allrows( ), ( [ 1, 1, 1 ], [ 2, Int, 1 ] ), 'Leaf rows from t4 UpRooted::Table';

load( $connection, 'postgresql', 'cleanup.sql' );


