Revision history for LTSV::LINQ

1.06  2026-03-23 JST (Japan Standard Time)

    Coding style aligned with DB-Handy and HTTP-Handy:
    - Module header: added Compatible/Platform comment block.
    - use strict/warnings order unified: use strict -> BEGIN{warnings stub}
      -> use warnings; local $^W = 1; -> BEGIN { pop @INC } (DB-Handy style).
    - $VERSION declared via use vars (aligned with DB-Handy/HTTP-Handy style).
    - Section separators changed from # ---...--- (65 chars) to
      ###...### (79 chars) matching DB-Handy and HTTP-Handy.
    - pmake.bat: install target now greps lib/**/*.pm only (DB-Handy style).

    Code style fixes (K-category):
    - K1: comma-space: my($s,$k) -> my($s, $k) in ThenBy* methods.
    - K2: \@items -> [ @items ] where passed as argument (OrderBy*, Reverse,
      GroupJoin).
    - K3: return \%hash exempted; no other \%hash violations in code.

    Test suite improvements (knowledge from DB-Handy and HTTP-Handy):

    Naming and style:
    - Renamed test files to 4-digit zero-padded hyphen format
      (001_basic.t -> 0001-basic.t, etc.).
    - Rewrote all functional test harnesses to DB-Handy/HTTP-Handy style:
      use strict, BEGIN{warnings stub}, BEGIN{pop @INC}, use FindBin / use lib,
      ($PASS, $FAIL, $T) variables, 1-line ok/is/like subs,
      print "1..N\n" plan, exit($FAIL ? 1 : 0) at end.
    - Removed shebang line (#!/usr/bin/perl) from t/0014-style.t.

    New test files:
    - t/0010-usascii.t: US-ASCII check for all MANIFEST files (replaces
      t/010_ascii_only.t which only checked lib/LTSV/LINQ.pm); doc/ files
      exempt (UTF-8 cheat sheets).
    - t/0015-perl5compat.t: Perl 5.005_03 compatibility checks (P1-P12)
      covering forbidden keywords, operators, VERSION self-assignment,
      warnings stub, and CVE-2016-1238 mitigation.
    - t/0016-cpan_precheck.t: comprehensive pre-publication check suite
      (categories A-K, 240 tests) ported from HTTP-Handy; covers file
      structure, version consistency, encoding, compatibility, style, META
      integrity, POD completeness, Changes format, and Makefile.PL;
      eg/*.pl included in C/E style checks.

    Samples and documentation:
    - eg/01_ltsv_query.pl: LTSV file query with FromLTSV/Where/Select/
      OrderByNumDescending/Distinct/ToLookup.
    - eg/02_array_query.pl: in-memory array queries, aggregation,
      Any/All, Skip/Take paging, Zip.
    - eg/03_grouping.pl: GroupBy, ToLookup, GroupJoin (left outer join),
      SelectMany with array-ref selector.
    - eg/04_sorting.pl: OrderBy/ThenBy multi-key sort, OrderByNum vs
      OrderByStr, Reverse.
    - doc/linq_cheatsheet.*.txt: LTSV::LINQ cheat sheets in 21 languages
      covering query creation, filtering, projection, sorting, grouping,
      set operations, joins, aggregation, and official spec links.
    - README: rewritten to DB-Handy/HTTP-Handy structure with NAME,
      SYNOPSIS, DESCRIPTION, INCLUDED DOCUMENTATION, INSTALLATION,
      COMPATIBILITY (Perl 5.005_03 philosophy), TARGET USE CASES,
      LIMITATIONS, AUTHOR, and COPYRIGHT AND LICENSE.

    Documentation fixes:
    - POD =head1 VERSION: corrected from "Version 1.05" to "Version 1.06".
    - POD TABLE OF CONTENTS: added missing sections (INCLUDED DOCUMENTATION,
      DESIGN PHILOSOPHY, LIMITATIONS AND KNOWN ISSUES, BUGS, SUPPORT);
      removed phantom entry (Data Source Methods is =head2, not =head1)
      and non-standard entries (AUTHOR, COPYRIGHT AND LICENSE).
    - POD: added =head1 INCLUDED DOCUMENTATION section listing eg/ and
      doc/ files (aligned with DB-Handy and HTTP-Handy).
    - POD DIAGNOSTICS: added four missing die-message entries:
      "Sequence contains more than one element" (Single),
      "Index must be non-negative" and "Index out of range" (ElementAt),
      "Invalid number of arguments for Aggregate" (Aggregate).
    - POD DIAGNOSTICS: added full =item C<...> entries with description
      and examples for all four new die messages.
    - README and eg/01_ltsv_query.pl: corrected method name
      FromFile -> FromLTSV (FromFile does not exist).
    - eg/01_ltsv_query.pl: removed shebang (#!/usr/bin/perl); added
      OrderBy to Demonstrates (used in code but previously unlisted).
    - eg/02_array_query.pl: added Contains example to match Demonstrates
      comment; corrected Demonstrates to include OrderByNumDescending;
      added ToArray to Demonstrates.
    - eg/03_grouping.pl: removed shebang; added Select, Sum, OrderBy,
      Distinct, ToArray to Demonstrates (all used in code).
    - eg/04_sorting.pl: removed shebang; corrected Demonstrates to match
      actual usage (removed OrderByDescending, ThenBy, ThenByDescending
      which are not used; added ThenByNumDescending, ThenByStr).
    - doc/linq_cheatsheet.*.txt: all 21 language cheat sheets rewritten
      with complete method coverage (60 methods, sections [1..12]);
      section 11 "Conversion methods" added (ToDictionary, ToLookup,
      ToLTSV, ToList); corrected Append/Prepend phantom entries removed;
      non-ASCII native scripts used for KO, ZH, TW, JA, TH, HI, BN,
      MY, KM, MN, NE, SI, UR (aligned with DB-Handy style).

1.05  2026-02-23 JST (Japan Standard Time)

    Perl 5.005_03 compatibility fixes:
    - warnings stub: added "package warnings; sub import {}" to the BEGIN
      block so that "use warnings" does not fail with
      "Can't locate object method 'import'" on Perl 5.005_03.
      Previously only $INC{'warnings.pm'} was set, which suppresses
      the file-load but not the method call.

    Correctness fix:
    - ToLTSV: sanitize record values before writing.  Values containing
      tab (\t), carriage return (\r), or newline (\n) are now mapped
      to a single space, preventing structural corruption of the LTSV
      output.  FromLTSV round-trips are now safe for any record value.
      Also handles undef values (written as empty string).

    Code quality:
    - Removed trailing whitespace from 24 lines (code and POD).

1.04  2026-02-21 JST (Japan Standard Time)

    New methods (6):
    - ThenBy($key_selector)
          Add ascending secondary sort key (smart comparison) to an
          LTSV::LINQ::Ordered sequence.  Returns a new Ordered object.
    - ThenByDescending($key_selector)
          Add descending secondary sort key (smart comparison).
    - ThenByStr($key_selector)
          Add ascending secondary sort key (string/cmp comparison).
    - ThenByStrDescending($key_selector)
          Add descending secondary sort key (string/cmp comparison).
    - ThenByNum($key_selector)
          Add ascending secondary sort key (numeric/<=>) comparison).
          Undefined or empty values treated as 0.
    - ThenByNumDescending($key_selector)
          Add descending secondary sort key (numeric/<=>) comparison).

    Architecture:
    - OrderBy* methods now return LTSV::LINQ::Ordered (subclass of
      LTSV::LINQ via @ISA), mirroring .NET LINQ's IOrderedEnumerable<T>.
      All existing LTSV::LINQ methods (Where, Select, Take, ...) are
      available through inheritance.  ThenBy* are only on Ordered objects.
    - Sorting uses Schwartzian-Transform decorated-array with original-
      element index as a final tie-breaker, guaranteeing completely stable
      multi-key sorting on all Perl versions including 5.005_03.
    - ThenBy* is non-destructive: each call returns a new Ordered object;
      the original is unchanged, so branching sort chains are safe.
    - Ordered objects are re-iterable (use _factory internally).

    Documentation:
    - Ordering Methods: section rewritten to cover ThenBy* family,
      IOrderedEnumerable analogy, stability guarantee, non-destructive
      semantics, and comparison-type families extended to include ThenBy*.
    - Method Summary Table: OrderBy* Returns column updated to OrderedQuery;
      ThenBy* rows added; footnote added explaining OrderedQuery.
    - Not Implemented / Compound Ordering: ThenBy* entry updated from
      "not implemented / workaround" to "implemented in v1.04".
    - Method count: 54 -> 60.

    Kwalitee fixes (for v1.03 issues reported by CPANTS):
    - META.json: removed top-level 'minimum_perl_version' key (not valid in
          CPAN::Meta::Spec v2; custom keys must begin with 'x_' or 'X_').
          Perl version requirement is already expressed correctly via
          prereqs.runtime.requires.perl.  META.yml retains the key (valid
          in META.yml spec v1.4).
    - SECURITY.md: new file added (satisfies has_security_doc and
          security_doc_contains_contact Kwalitee indicators).
          Contains vulnerability reporting address ina@cpan.org.
    - pmake.bat: updated to generate SECURITY.md and to omit
          minimum_perl_version from the META.json template.

    Tests:
    - t/013_v104_thenby.t: new file, 42 tests.
          Covers: return type (LTSV::LINQ::Ordered), ThenBy/ThenByDescending,
          three-key sort, stability, non-destructive branching,
          OrderByDescending + ThenBy, smart vs Str vs Num for ThenBy,
          ThenByNum undef, ThenByNumDescending, ThenByStrDescending,
          chaining with Where/Select/Count/First/Last/Take/Skip,
          empty/single-element sequences, re-iterability, LTSV scenario.
    - Total: 258 -> 300 tests across 13 files.

1.03  2026-02-20 JST (Japan Standard Time)

    New methods (6):
    - Join($inner, $outer_key, $inner_key, $result)
          Inner join; inner sequence is fully buffered at call time.
    - GroupJoin($inner, $outer_key, $inner_key, $result)
          Left outer join; inner sequence fully buffered.
          Inner group passed to result_selector as a re-iterable
          LTSV::LINQ object (supports Count, Sum, Any, Where, etc.
          called multiple times on the same group).
    - OrderByStr($key_selector)
          Sort ascending using string comparison (cmp) unconditionally.
    - OrderByStrDescending($key_selector)
          Sort descending using string comparison (cmp) unconditionally.
    - OrderByNum($key_selector)
          Sort ascending using numeric comparison (<=>) unconditionally.
          Undefined keys treated as 0.
    - OrderByNumDescending($key_selector)
          Sort descending using numeric comparison (<=>) unconditionally.

    Behavioural changes:
    - GroupBy: groups are now returned in insertion order (first-seen key),
          matching .NET LINQ behaviour.  Previously sorted alphabetically.
    - SelectMany: selector must now return an ARRAY reference; returning any
          other type dies with "SelectMany: selector must return an ARRAY
          reference".  Previously non-ARRAY values were passed through
          silently (behaving like Select).
    - Distinct: without a key_selector, hash references and array references
          are now compared by content (via internal _make_key), consistent
          with Intersect and Except.  Previously compared by reference
          address (stringification), so structurally equal hashrefs were
          not deduplicated.
    - iterator(): enhanced to support _factory-based re-iteration, enabling
          GroupJoin inner groups to be iterated multiple times.
    - FirstOrDefault / LastOrDefault: fixed critical bug where a single
          non-CODE argument was treated as a predicate, causing a crash.
          A scalar argument is now correctly used as the default value.
    - LastOrDefault: added optional $default argument to match the
          FirstOrDefault([$predicate,] $default) signature.

    Documentation:
    - ARCHITECTURE: Method Categories replaced by a 54-row
          Lazy/Materialising table (Evaluation + Returns columns).
    - ARCHITECTURE: Memory Characteristics updated to match the table.
    - COMPATIBILITY: new ".NET LINQ Compatibility" section listing exact
          matches and intentional differences (SingleOrDefault, DefaultIfEmpty,
          OrderBy smart comparison, EqualityComparer, query syntax).
    - Ordering Methods: section header added explaining stable sort
          (Perl 5.8+ guarantee) and the three comparison families.
    - Set Operations: section header documenting partially-eager evaluation
          (second sequence buffered at call time).
    - Join Operations: section header documenting partially-eager evaluation
          (inner sequence buffered at call time).
    - GroupBy: note updated: "insertion order" replacing "sorted key order".
    - LIMITATIONS: "GroupBy Sorts Keys" entry removed (no longer true).
    - FromLTSV: file-handle management note added.
    - Where DSL: explicit note that arguments must be even-count key=>value pairs.
    - COOKBOOK: two new patterns: "Iterator consumption / snapshot" and
          "Efficient large-file pattern".
    - SelectMany: Important note updated to reflect die behaviour.
    - DIAGNOSTICS: new entry "SelectMany: selector must return an ARRAY
          reference"; FromLTSV entry expanded with file-handle note.
    - DESIGN PHILOSOPHY: new section (Perl 5.005_03 compatibility rationale,
          US-ASCII only policy, $VERSION idiom, design principles).
    - Method count: 50 -> 54.

    Tests:
    - t/004_grouping.t: 8 tests -> 16 tests.
          Added: GroupBy insertion order (3 tests),
                 Distinct content-equality for hashrefs/arrayrefs (5 tests).
    - t/005_complex.t: 10 tests -> 14 tests.
          Added: SelectMany dies on non-ARRAY return (2 tests),
                 SelectMany empty/mixed arrayref (2 tests).
    - t/012_v103_ordering.t: new file, 40 tests.
          Covers OrderByStr, OrderByStrDescending, OrderByNum,
          OrderByNumDescending; stable sort; smart vs Str vs Num contrast;
          LTSV realistic scenarios; edge cases.
    - Total: 246 -> 258 tests across 12 files.

1.02  2026-02-17 JST (Japan Standard Time)

    - Added 6 new methods for relational operations and utilities

    New methods:
    - Data sources: Empty, Repeat
    - Concatenation: Zip
    - Join operations: Join
    - Conversion: ToDictionary, ToLookup

    Improvements:
    - Enhanced POD documentation with detailed examples
    - Updated method summary table (45 -> 49 methods)
    - Ensured all source code is US-ASCII only (no multibyte characters)
    - Added test for ASCII-only verification
    - Method count: 49 methods across 15 categories

1.01  2026-02-16 JST (Japan Standard Time)

    - Added 14 new methods to enhance LINQ compatibility

    New methods:
    - Element access: LastOrDefault, Single, SingleOrDefault,
                      ElementAt, ElementAtOrDefault
    - Quantifier: Contains
    - Concatenation: Concat
    - Partitioning: SkipWhile
    - Default value: DefaultIfEmpty
    - Aggregation: Aggregate
    - Set operations: Union, Intersect, Except
    - Comparison: SequenceEqual

    Improvements:
    - Enhanced POD documentation for all new methods
    - Added comprehensive examples for each method
    - Updated method summary table (31 -> 45 methods)
    - Improved test coverage
    - Optimized Single/ElementAt to use lazy evaluation (O(1) memory)
    - Fixed Makefile.PL version inconsistency
    - Clarified Perl 5.005_03 specification philosophy
    - Added .NET LINQ compatibility notes

1.00  2026-02-15 JST (Japan Standard Time)

    - Initial release
