﻿T1 := Range(10)->{ A: it, B: it * it, C: "Blah_" & ToText(it), D: it mod 3 = 0, };
T1;
PC := "mytable1.rbin";
finish WriterC as WriteRbin(T1, Link.LocalData("temp/" & PC), true, false);
"*** Wrote table to '" & WriterC.Link.Path & "' ***";
(WriterC$State, WriterC$Finished, WriterC$Failed, WriterC$ResultNames);
(WriterC.Size, WriterC.Compression);

PU := "mytable1-unchunked.rbin";
finish WriterU as WriteRbin(T1, "temp/" & PU, false, false);
"*** Wrote table to '" & WriterU.Link.Path & "' ***";
(WriterU$State, WriterU$Finished, WriterU$Failed, WriterU$ResultNames);
(WriterU.Size, WriterU.Compression);

finish ReaderC as ReadRbin(WriterC.Link);
(ReaderC$State, ReaderC$Finished, ReaderC$Failed, ReaderC$ResultNames);
"*** Read table from '" & ReaderC.Link.Path & "' ***";
(ReaderC.FullLink.Path.Len > ReaderC.Link.Path.Len, ReaderC.FullLink.Path->IndexOf(PC) >= 0, ReaderC.Link.Path->IndexOf(PC) >= 0);
ReaderC.RowCount;
ReaderC.Data;

finish ReaderU as ReadRbin(WriterU.Link);
(ReaderU$State, ReaderU$Finished, ReaderU$Failed, ReaderU$ResultNames);
"*** Read table from '" & ReaderU.Link.Path & "' ***";
(ReaderU.FullLink.Path.Len > ReaderU.Link.Path.Len, ReaderU.FullLink.Path->IndexOf(PU) >= 0, ReaderU.Link.Path->IndexOf(PU) >= 0);
ReaderU.RowCount;
ReaderU.Data;

"*** Write/read non-opt primitive types. ***";
T2 := [
    (1ia shl 7) - 1,
    (1ia shl 7),
    (1ia shl 8) - 1,
    (1ia shl 8),
    (1ia shl 15) - 1,
    (1ia shl 15),
    (1ia shl 16) - 1,
    (1ia shl 16),
    (1ia shl 31) - 1,
    (1ia shl 31),
    (1ia shl 32) - 1,
    (1ia shl 32),
    (1ia shl 63) - 1,
    (1ia shl 63),
    (1ia shl 64) - 1,
    (1ia shl 64),
]
->{
    IA: CastIA(it),
    I8: CastI8(it), I4: CastI4(it), I2: CastI2(it), I1: CastI1(it),
    U8: CastU8(it), U4: CastU4(it), U2: CastU2(it), U1: CastU1(it),
    R8: CastR8(it / 4), R4: CastR4(it / 4),
    B:  it band 1 != 0,
    S: ToText(it),
    D1: CastDate(it), // Ticks.
    T1: CastTime(it),
    D2: CastDate(it * 10_000_000), // Seconds.
    T2: CastTime(it * 10_000_000),
    D3: CastDate(it * (10_000_000 * 60)), // Minutes.
    T3: CastTime(it * (10_000_000 * 60)),
};
T2;
T2.IA;
T2.I8;
T2.I4;
T2.I2;
T2.I1;
T2.U8;
T2.U4;
T2.U2;
T2.U1;
T2.R8;
T2.R4;
T2.B;
T2.S;
T2.D1;
T2.D2;
T2.D3;
T2.T1;
T2.T2;
T2.T3;

P := "mytable2.rbin";
finish Writer as WriteRbin(T2, "temp/" & P, true, false);
(Writer.Size, Writer.Compression);
finish Reader as ReadRbin(Writer.FullLink);
(Reader.FullLink.Path.Len = Reader.Link.Path.Len, Reader.FullLink.Path->IndexOf(P) >= 0, Reader.Link.Path->IndexOf(P) >= 0);
Reader.RowCount;
RT2 := Reader.Data;

RT2;
RT2.IA;
RT2.I8;
RT2.I4;
RT2.I2;
RT2.I1;
RT2.U8;
RT2.U4;
RT2.U2;
RT2.U1;
RT2.R8;
RT2.R4;
RT2.B;
RT2.S;
RT2.D1;
RT2.D2;
RT2.D3;
RT2.T1;
RT2.T2;
RT2.T3;
ForEach(a:T2, b:RT2, (
    "_" if a.I8 = b.I8 else "X",
    "_" if a.I4 = b.I4 else "X",
    "_" if a.I2 = b.I2 else "X",
    "_" if a.I1 = b.I1 else "X",
    "_" if a.U8 = b.U8 else "X",
    "_" if a.U4 = b.U4 else "X",
    "_" if a.U2 = b.U2 else "X",
    "_" if a.U1 = b.U1 else "X",
    "_" if a.R8 = b.R8 else "X",
    "_" if a.R4 = b.R4 else "X",
    "_" if a.B  = b.B  else "X",
    "_" if a.S  = b.S  else "X",
    "_" if a.D1 = b.D1 else "X",
    "_" if a.D2 = b.D2 else "X",
    "_" if a.D3 = b.D3 else "X",
    "_" if a.T1 = b.T1 else "X",
    "_" if a.T2 = b.T2 else "X",
    "_" if a.T3 = b.T3 else "X",
));

"*** Write/read opt primitive types. ***";
T3 := T2 ++ [{}];
T3;
finish Writer as WriteRbin(T3, "temp/mytable3.rbin", true, false);
RT3 := ReadRbin(Writer.FullLink);
RT3;
RT3.IA;
RT3.I8;
RT3.I4;
RT3.I2;
RT3.I1;
RT3.U8;
RT3.U4;
RT3.U2;
RT3.U1;
RT3.R8;
RT3.R4;
RT3.B;
RT3.S;
RT3.D1;
RT3.D2;
RT3.D3;
RT3.T1;
RT3.T2;
RT3.T3;
ForEach(a:T3, b:RT3, (
    "_" if a.I8 = b.I8 else "X",
    "_" if a.I4 = b.I4 else "X",
    "_" if a.I2 = b.I2 else "X",
    "_" if a.I1 = b.I1 else "X",
    "_" if a.U8 = b.U8 else "X",
    "_" if a.U4 = b.U4 else "X",
    "_" if a.U2 = b.U2 else "X",
    "_" if a.U1 = b.U1 else "X",
    "_" if a.R8 = b.R8 else "X",
    "_" if a.R4 = b.R4 else "X",
    "_" if a.B  = b.B  else "X",
    "_" if a.S  = b.S  else "X",
    "_" if a.D1 = b.D1 else "X",
    "_" if a.D2 = b.D2 else "X",
    "_" if a.D3 = b.D3 else "X",
    "_" if a.T1 = b.T1 else "X",
    "_" if a.T2 = b.T2 else "X",
    "_" if a.T3 = b.T3 else "X",
));

"*** Write/read opt records. ***";
finish Writer as WriteRbin(T3 ++ [null], "temp/mytable3-opt.rbin", true, false);
RT3N := ReadRbin(Writer.FullLink);
RT3N;
ForEach(a:T3 ++ [null], b:RT3N, (
    "_" if a.I8 = b.I8 else "X",
    "_" if a.I4 = b.I4 else "X",
    "_" if a.I2 = b.I2 else "X",
    "_" if a.I1 = b.I1 else "X",
    "_" if a.U8 = b.U8 else "X",
    "_" if a.U4 = b.U4 else "X",
    "_" if a.U2 = b.U2 else "X",
    "_" if a.U1 = b.U1 else "X",
    "_" if a.R8 = b.R8 else "X",
    "_" if a.R4 = b.R4 else "X",
    "_" if a.B  = b.B  else "X",
    "_" if a.S  = b.S  else "X",
    "_" if a.D1 = b.D1 else "X",
    "_" if a.D2 = b.D2 else "X",
    "_" if a.D3 = b.D3 else "X",
    "_" if a.T1 = b.T1 else "X",
    "_" if a.T2 = b.T2 else "X",
    "_" if a.T3 = b.T3 else "X",
));

"*** Write/read zero rows. ***";
T4 := T2->TakeIf(I8 = 1);
T4;
finish Writer as WriteRbin(T4, "temp/mytable4.rbin", true, false);
RT4 := ReadRbin(Writer.FullLink);
RT4;

"*** Write/read zero columns (throws). ***";
T5 := Range(10)->{ };
T5;
finish Writer as WriteRbin(T5, "temp/mytable5.rbin", true, false); // Throws.
(Writer$State, Writer$Finished, Writer$Failed, Writer$ErrorMessage, Writer$ResultNames);
RT5 := ReadRbin(Writer.FullLink); // Writer.FullLink invalid.
RT5;

"*** Write type with g (bind error). ***";
T6 := Range(2)->CastGenLift() ++ Range(2)->{A:it};
T6;
finish Writer as WriteRbin(T6, "temp/mytable6.rbin", true, false); // Error.
