Biblio::Isis(3pm)

πŸ“¦
version 0.24 Β· 2 versions
, in debian bookworm, ubuntu jammy, ubuntu noble

πŸ’– Biblio::Isis β€” the manual page, but make it make sense πŸ’–

okay so bestie, you found the docs for Biblio::Isis (that's the 3pm perl manual page, she's from the User Contributed Perl Documentation section, very demure, very mindful). Sit down, grab a strawberry πŸ“, and let's get into it.


✨ NAME ✨

Biblio::Isis β€” read CDS/ISIS, WinISIS and IsisMarc databases. That's the whole vibe. Slay. 🌈


πŸŽ€ SYNOPSIS πŸŽ€

Look at her go:

use Biblio::Isis;

my $isis = new Biblio::Isis(
      isisdb => './cds/cds',
);

for(my $mfn = 1; $mfn <= $isis->count; $mfn++) {
      print $isis->to_ascii($mfn),"\n";
}

That's it. That's the whole main character moment. πŸ‘‘


πŸ¦‹ DESCRIPTION πŸ¦‹

So this module reads ISIS databases β€” the ones made by DOS CDS/ISIS, WinIsis or IsisMarc. It's your perl-only alternative to the OpenIsis module, which is lowkey out here deprecating its old "XS" bindings for perl. not me side-eyeing that decision πŸ’…

She can make you:

  • hash values from the data in the ISIS database (with "to_hash")
  • an ASCII dump (with "to_ascii")
  • or just a hash with field names and packed values, like "^asomething^belse"

The unique feature of this module β€” the thing that's giving main character energy β€” is that it can "include_deleted" records. 🫢 It also skips zero-sized fields, because OpenIsis has a bug in the XS bindings where zero sized fields get filled with random junk from memory, and we are NOT doing that.

It also has support for identifiers, but only if the ISIS database was created by IsisMarc β€” see "to_hash" for the tea. β˜•

Now, real talk: this module will always be slower than the OpenIsis module, because OpenIsis uses a C library and this one is perl. But here's the thing β€” since it's written in perl, it's platform independent (so you don't need a C compiler, iconic πŸ’…) and it can be easily modified. The author hopes it creates data structures that are easier to use than the ones OpenIsis creates, so the time you save in other parts of your code should compensate for the slower performance. And honestly? Speed of reading an ISIS database is rarely an issue. periodt. ✨


🌸 METHODS 🌸

πŸ’œ new

Open an ISIS database. Here's the flex:

my $isis = new Biblio::Isis(
      isisdb => './cds/cds',
      read_fdt => 1,
      include_deleted => 1,
      hash_filter => sub {
              my ($v,$field_number) = @_;
              $v =~ s#foo#bar#g;
      },
      debug => 1,
      join_subfields_with => ' ; ',
);

The options are described below, bestie. Every single one. πŸ’…

  • isisdb β€” full or relative path to the ISIS database files. This includes the common prefix of ".MST", and ".XRF" and optionally ".FDT" (if you're using the "read_fdt" option). In the example above it uses "./cds/cds.MST" and related files. πŸ—‚οΈ
  • read_fdt β€” boolean flag, specifies if the field definition table should be read. It's off by default.
  • include_deleted β€” don't skip logically deleted records in ISIS. the drama of it all πŸ’€
  • hash_filter β€” a filter code ref that gets used before data is converted to hash. It receives two arguments: the whole line from the current field (in $_[0]) and the field number (in $_[1]).
  • debug β€” dump a lot of debugging output, even at level 1. For even more, increase the level. πŸ“’
  • join_subfields_with β€” define the delimiter used to join repeatable subfields. This option exists to support legacy applications written against versions older than 0.21 of this module. By default it's disabled. See "to_hash".
  • ignore_empty_subfields β€” remove all empty subfields while reading from the ISIS file. 🧹

πŸ’– count

Return the number of records in the database.

print $isis->count;

πŸ’… fetch

Read the record with the selected MFN.

my $rec = $isis->fetch(55);

Returns a hash where the keys are field names and the values are unpacked values for that field, like this:

$rec = {
  '210' => [ '^aNew York^cNew York University press^dcop. 1988' ],
  '990' => [ '2140', '88', 'HAY' ],
};

πŸŽ€ mfn

Returns the current MFN position.

my $mfn = $isis->mfn;

πŸ¦‹ to_ascii

Returns ASCII output of the record with the specified MFN.

print $isis->to_ascii(42);

Which outputs something like this:

210   ^aNew York^cNew York University press^dcop. 1988
990   2140
990   88
990   HAY

And if "read_fdt" was specified when you called "new", it will display field names from the ".FDT" file instead of numeric tags. glow up ✨


🌈 to_hash

Read the record with the specified MFN and convert it to a hash.

my $hash = $isis->to_hash($mfn);

She has the ability to convert characters (using "hash_filter") from the ISIS database before creating structures, which enables character re-mapping or quick fix-up of data. πŸ”₯

This function returns a hash which looks like this:

$hash = {
  '210' => [
             {
               'c' => 'New York University press',
               'a' => 'New York',
               'd' => 'cop. 1988'
             }
           ],
  '990' => [
             '2140',
             '88',
             'HAY'
           ],
};

You can later use that hash to produce literally any output from your ISIS data. πŸ’…

If the database was created using IsisMarc, it will also have two special fields which get used for identifiers, "i1" and "i2", like this:

'200' => [
           {
             'i1' => '1',
             'i2' => ' '
             'a' => 'Goa',
             'f' => 'Valdo D\'Arienzo',
             'e' => 'tipografie e tipografi nel XVI secolo',
           }
         ],

In case there are repeatable subfields in the record, this will create the following structure:

'900' => [ {
      'a' => [ 'foo', 'bar', 'baz' ],
}]

Or, in the more complex example of

902   ^aa1^aa2^aa3^bb1^aa4^bb2^cc1^aa5

it will create

902   => [
      { a => ["a1", "a2", "a3", "a4", "a5"], b => ["b1", "b2"], c => "c1" },
],

This behaviour can be changed using the "join_subfields_with" option to "new", in which case "to_hash" will always create a single value for each subfield. This will change the result to:

(the original doc just says that and then moves on β€” no, bestie, I don't know either, that's literally what it says πŸ™ˆ)

This method will also create an additional field 000 with the MFN. 🫢

There's also a more elaborative way to call "to_hash", like this:

my $hash = $isis->to_hash({
      mfn => 42,
      include_subfields => 1,
});

Each option controls creation of the hash:

  • mfn β€” specify the MFN number of the record.
  • include_subfields β€” this option will create an additional key in the hash called "subfields", which will have the original record subfield order and index to that subfield, like this:
  902   => [ {
        a => ["a1", "a2", "a3", "a4", "a5"],
        b => ["b1", "b2"],
        c => "c1",
        subfields => ["a", 0, "a", 1, "a", 2, "b", 0, "a", 3, "b", 1, "c", 0, "a", 4],
  } ],
  • join_subfields_with β€” define the delimiter which will be used to join repeatable subfields. You can specify this option here instead of in "new" if you want per-record control. πŸ‘‘
  • hash_filter β€” you can override the "hash_filter" defined in "new" using this option.

⭐ tag_name

Return the name of the selected tag.

print $isis->tag_name('200');

🧚 read_cnt

Read the content of the ".CNT" file and return a hash containing it.

print Dumper($isis->read_cnt);

This function is not used by the module β€” ".CNT" files are not required for this module to work β€” but it can be useful to examine your index, like while debugging for example. πŸ”


πŸ’€ unpack_cnt

Unpack one of the two 26 byte fixed length records in the ".CNT" file.

Here's the definition of the record:

off key        description                             size
 0: IDTYPE     BTree type                              s
 2: ORDN       Nodes Order                             s
 4: ORDF       Leafs Order                             s
 6: N          Number of Memory buffers for nodes      s
 8: K          Number of buffers for first level index s
10: LIV        Current number of Index Levels          s
12: POSRX      Pointer to Root Record in N0x           l
16: NMAXPOS    Next Available position in N0x          l
20: FMAXPOS    Next available position in L0x          l
24: ABNORMAL   Formal BTree normality indicator        s
length: 26 bytes

This will fill the $self object under "cnt" with a hash. It's used by "read_cnt".


😭 BUGS 😭

Some parts of the CDS/ISIS documentation are just not detailed enough to explain some variations in the input databases that have been tested with this module. When the author was in doubt, they assumed OpenIsis's implementation was right β€” except for the obvious bugs, obviously. πŸ™ˆ

However, every effort has been made to test this module with as many databases (and as many programs that create them) as possible. we love a thorough queen πŸ’…

The author would be very grateful for success or failure reports about using this module with databases from programs other than WinIsis and IsisMarc. They tested it against the output of one "isis.dll"-based application, but they don't know any details about its version. So if you've got receipts, send them. πŸ“©


🌟 VERSIONS 🌟

Since this is a young module, new features get added in subsequent versions. It's a good idea to specify the version when you use this module, like this:

use Biblio::Isis 0.23

Below is the list of changes in specific versions of the module β€” so you can target older versions if you really have to:

  • 0.24 β€” Added "ignore_empty_subfields"
  • 0.23 β€” Added "hash_filter" to "to_hash"; fixed a bug with the documented "join_subfields_with" in "new" which wasn't implemented
  • 0.22 β€” Added field number when calling "hash_filter"
  • 0.21 β€” Added "join_subfields_with" to "new" and "to_hash"; added "include_subfields" to "to_hash"
  • 0.20 β€” Added $isis->mfn, support for repeatable subfields, and the $isis->to_hash({ mfn => 42, ... }) calling convention

πŸ‘‘ AUTHOR πŸ‘‘

        Dobrica Pavlinusic
        CPAN ID: DPAVLIN
        dpavlin@rot13.org
        http://www.rot13.org/~dpavlin/

This module is based heavily on code from the "LIBISIS.PHP" library to read ISIS files V0.1.1, written in php and (c) 2000 Franck Martin <franck@sopac.org> and released under LGPL. giving credit where credit is due, always 🫢


This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the LICENSE file included with this module. πŸ“„


🌈 SEE ALSO 🌈


and that's the whole page, bestie. no notes. πŸ’…

sign-off time: this little beauty is perl v5.32.1, dated 2021-12-26, and she lives her life as Biblio::Isis(3pm). go read some databases, you icon βœ¨πŸ‘‘πŸ¦‹

πŸ“¦ where this page comes from