### ----------------------------------------------------
### -- Duckie
### -- Licenses: MIT
### -- Authors: Brian Duggan
### -- File: t/03-column-data.rakutest
### ----------------------------------------------------
use Test;
use Duckie::DuckDB::Native;
use NativeCall;
plan 31;

my $db-file will leave { .unlink if .IO.e } = $*TMPDIR.child('test.db');
my DuckDB::Native::Database $dbh .= new;
my DuckDB::Native::Connection $conn .= new;
my DuckDB::Native::Result $res .= new;

is duckdb_open($db-file.Str, $dbh), +DUCKDB_SUCCESS, 'open';
is duckdb_connect($dbh, $conn) , +DUCKDB_SUCCESS, 'connect';

is duckdb_query($conn, 'select 99 as first, 10.22 as second', $res), +DUCKDB_SUCCESS, 'select';
is duckdb_column_count($res), 2, 'two columns';
duckdb_destroy_result($res);

{ # integer
  is duckdb_query($conn, 'select 99 as first, 10.22 as second', $res), +DUCKDB_SUCCESS, 'select';
  is duckdb_column_type($res, 0), +DUCKDB_TYPE_INTEGER, 'first column type';
  my $data = duckdb_column_data($res, 0);
  my $values = nativecast(Pointer[int32], $data);
  is $values[0], 99, 'first column data';
  duckdb_destroy_result($res);
}

{ # decimal
  is duckdb_query($conn, 'select 99 as first, 10.22 as second', $res), +DUCKDB_SUCCESS, 'select';
  is duckdb_column_type($res, 1), +DUCKDB_TYPE_DECIMAL, 'second column type';
  my $data = duckdb_column_data($res, 1);
  my $values = nativecast(Pointer[int],$data);
  my $type = duckdb_column_logical_type($res,1);
  my $width = duckdb_decimal_width($type);
  my $scale = duckdb_decimal_scale($type);
  is $values[0], 1022, 'second column data';
  is $width, 4, 'width';
  is $scale, 2, 'scale';
  my $rat = Rat.new($values[0], 10**$scale);
  is $rat, 10.22, 'Rat';
  is duckdb_decimal_internal_type($type), +DUCKDB_TYPE_SMALLINT, 'internal type';
  duckdb_destroy_result($res);
}

{ # float
  is duckdb_query($conn, 'select cast(10.22 as float) as first', $res), +DUCKDB_SUCCESS, 'select';
  is duckdb_column_type($res, 0), +DUCKDB_TYPE_FLOAT, 'second column type';
  my $data = duckdb_column_data($res, 0);
  my $values = nativecast(Pointer[num32],$data);
  ok $values[0] ~~ Num, 'num';
  is round($values[0],0.01), 10.22, 'second column data';
  duckdb_destroy_result($res);
}

{ # double
  is duckdb_query($conn, 'select cast(10.22 as double) as first', $res), +DUCKDB_SUCCESS, 'select';
  is duckdb_column_type($res, 0), +DUCKDB_TYPE_DOUBLE, 'second column type';
  my $values = nativecast(Pointer[num], duckdb_column_data($res, 0) );
  ok $values[0] ~~ Num, 'num';
  is round($values[0],0.01), 10.22, 'second column data';
  duckdb_destroy_result($res);
}

{ # null
  is duckdb_query($conn, 'select NULL, 42', $res), +DUCKDB_SUCCESS, 'select null';
  my $mask = nativecast(Pointer[int8], duckdb_nullmask_data($res, 0));
  is $mask[0], 1, 'null mask';
  my $mask2 = nativecast(Pointer[int8], duckdb_nullmask_data($res, 1));
  is $mask2[0], 0, 'null mask';
  duckdb_destroy_result($res);
}

{ # date
  is duckdb_query($conn, q[select date '1970-01-02' as day_1, date '2024-04-01' as nother_day], $res), +DUCKDB_SUCCESS, 'select date';
  my $col = duckdb_column_data($res, 0);
  my $values = nativecast(Pointer[DuckDate], $col);
  my $duck-date = $values.deref;
  is $duck-date.Date, '1970-01-02', 'date';
  my $nother = duckdb_column_data($res, 1);
  my $second-col = nativecast(Pointer[DuckDate], $nother);
  is $second-col.deref.Date, '2024-04-01', 'nother date';
  #my $date = duckdb_from_date($duck-date); # seg faults
  duckdb_destroy_result($res);
}

{ # timestamp
  is duckdb_query($conn, q[select timestamp '1970-01-02 00:00:00' as ts_1, timestamp '2024-04-01 12:34:56' as ts_2], $res), +DUCKDB_SUCCESS, 'select timestamp';
  is nativecast(Pointer[DuckTimestamp], duckdb_column_data($res, 0) ).deref.DateTime, '1970-01-02T00:00:00Z', 'timestamp';
  is nativecast(Pointer[DuckTimestamp], duckdb_column_data($res, 1) ).deref.DateTime, '2024-04-01T12:34:56Z', 'nother timestamp';
}

duckdb_disconnect($conn);
duckdb_close($dbh);


