NAME

Config::XrmDatabase - Pure Perl X Resource Manager Database

VERSION

version 0.07

SYNOPSIS

  $db = Config::XrmDatabase->new;
  $db->insert( '*b.c.d', 'v1' );
  $db->query( 'A.B.C.D', 'a.b.c.d' );

DESCRIPTION

This is a Pure Perl implementation of the X Window Resource Manager Database (XrmDB). It allows creation and manipulation of Xrm compliant databases.

Warning! The XrmDB refers to names and resources. These days they are more typically called keys and values. The terminology used below (and sometimes in the names of subroutines and methods) mixes these two approaches, sometimes a bit too liberally. Subroutine and method names will probably change to make things more consistent.

Why another configuration database?

The XrmDB differs from typical key-value stores by allowing stored keys to be either fully or partially qualified. For example, the partially qualified key

    *.c.d

will match a query for the keys a.c.d, a.b.c.d. Keys are composed of multiple components separated by the . character. If the component is ? it will match any single component; a component of * matches any number (including none).

Matching

Matching a search key against the database is a component by component operation, starting with the leftmost component. The component in the search key is checked against the same level component in the database keys. First the keys with non-wildcard components are compared; if there is an exact match, the search moves on to the next component in the matching database key.

At this point, XrmDB adds another dimension to the search. Keys belong to a class, which has the same number of components as the key. When an exact match against the search key component is not found, the database is searched for an exact match for the same level component in the class.

Only after that fails does the algorithm switch to database keys with wildcard components. The same order of comparison is performed; first against the component in the search key, and if that fails, to the component in the class.

For example, given a search key of

 xmh.toc.messagefunctions.incorporate.activeForeground'

with a class of

 Xmh.Paned.Box.Command.Foreground

the database is first searched for keys which begin with xmh. If that fails, the database is searched for keys which begin with Xmh. If that fails, keys which start with a ? wildcard are searched, and then those which start with *. The * components can match an arbitrary number of components in the search key and class.

If a match is found, the search moves on to the next unmatched component and the algorithm is repeated.

Classes

Why the extra class?

Assigning keys to a class provides an ability to distinguish between two similarly structured keys. It essentially creates namespaces for keys so that values can be created based on which namespace a key belongs to, rather than the content of the key.

Let's say that you have a bunch of keys which end in Foreground:

  a.b.c.Foreground
  d.e.f.Foreground
  x.y.z.Foreground

and you want to set a value for any keys which end in Foreground:

  *.Foreground : 'yellow'

To specify a separate value for each one could set

  a.b.c.Foreground : 'red'
  d.e.f.Foreground : 'blue'
  x.y.z.Foreground : 'green'

Let's say that a.b.c.Foreground and d.e.f.Foreground are in the same class, U.V.W.Foreground, and all keys in that class should have the same value:

  U.V.W.Foreground : 'red'
  x.y.z.Foreground : 'green'

At some point, a new hierarchy of keys that begin with g is added to that class, but they should has a different value:

  g.V.W.Foreground : 'magenta'

You could try this:

  g.?.?.Foreground : 'magenta'

But that would affect all keys that begin with g but aren't in that class.

Classes help bring some order, but this system can become very confusing if some discipline isn't maintained.

CLASS METHODS

new

  $db = Config::XrmDatabase->new( \%args );

The class constructor; it constructs an empty database.

The available constructor arguments are:

query_return_value

This option sets the default value for the "query" method's return_value parameter. It defaults to the string value. See "query" for more details.

query_on_failure

This option sets the default value for the "query" method's on_failure parameter. It defaults to the string undef. See "query" for more details.

insert hash

Populate the database with the supplied data.

read_file

  $db = read_file( $class, $file, %opts );

Create a database from a simplified version of the X Resource Manager database file. Each record is a single line of the form

  key : value

Multiline values are not parsed properly.

%opts is passed to the class constructor.

METHODS

insert

  $db->insert( $key, $value );

Insert the $key, $value pair.

$match may be partially or fully qualified (see "Match Keys" );

query

  $value = $db->query( $class, $name, %options );

Query the $class, $name pair. $class and $name must be fully qualified (see "Matching" ). If no match was found, undef is returned. To disambiguate an actual value of undef, use the value => 'all' option.

Default values for some options can be set when the database object is constructed. See "new". The following options are recognized:

return_value

This option determines what is returned. The following string values are accepted.

value

The value stored in the DB. This is the default.

reference

A reference to the value. This allows disambiguation between an undef returned as a value and an undef returned to indicate there was no match, e.g.,

   $db->insert( 'key', undef );
   $value = $db->query('foo', return_value => 'reference' );
   die( "no match unless defined $value" );
   $value = $$value;
   say "defined = ", defined $value ? 'yes' : 'no';
all

A hash containing all of the data associated with the database entry. Currently this includes

value

The value stored in the DB.

key

An internal representation of the key which matched. Use Config::XrmDatabase::Util::name_arr_to_str to convert it to a normalized string.

match_count

The number of times this key was matched.

on_failure

The action to be taken if the query fails. The following values are accepted:

The string 'throw'

An exception of class Config::XrmDatabase::Failure::query is thrown.

The string 'undef'

The undefined value is returned.

A reference to a subroutine

The reference will be called as

   return $subref->( $name, $class );

Note that the subroutine's return value will be returned by query.

write_file

  $db->write_file( $file );

Write a simplified form of an X Resource Manager database file. See "to_string" for the format.

to_string

  $string = $db->to_string( );

Encode a simplified form of an X Resource Manager database as a string.

Each record is a single line of the form

  key : value

Multiline values are not supported, and will create an unparseable result.

merge

  $db1->merge( $db2);

Merge another database into the existing one. Common entries are overwritten.

clone

  $db1 = $db->clone;

Return a detached clone.

to_kv

  \%hash = $db->to_kv( \%opt );

Return a copy of the db as a hash.

The optional %opt hash determines the content of the returned values. Keys are returned as normalized strings, equivalent to the form accepted by "insert".

It takes the following entries:

value

This option determines the form and content of the returned values.

value

The value stored when the DB entry was created. This is the default.

match_count

The number of times the key was successfully matched by queries against the database.

all

A hash containing all of the data associated with the key. Currently this includes value and match_count

to_kv_arr

  \@array = $db->to_kv_arr( value => $VALUE );

Return a copy of the db as a list of key, value pairs. The pairs are stored in an array, e.g.

  @array = ( [ $key, $value ], [ $key, $value ], ... );

Keys are returned as array references whose elements are the individual components (including wildcards), e.g.

  @array = ( [ [ 'a', '*', 'c' ], $value ], ... );

The optional %opt hash determines the content of the returned values. It takes the following entries:

value

This option determines the form and content of the returned values.

value

The value stored when the DB entry was created. This is the default.

match_count

The number of times the key was successfully matched by queries against the database.

all

A hash containing all of the data associated with the key. Currently this includes value and match_count

TO_HASH

  $db->TO_HASH;

Convert the DB object into a hash. Useful? Who knows?

See "to_kv" for a perhaps more useful output.

EXCEPTIONS

Exception objects which are thrown are in the Config::XrmDatabase::Failure namespace.

They stringify to a detailed message, which is also available via the msg method.

components

There is a mismatch in components between a key and its class.

file

There was an error in reading or writing a file.

internal

Something went wrong that shouldn't have

key

An illegal key was specified.

parameter

Something was wrong with a passed in parameter

INCOMPATIBILITIES

  • This module does not interface with the X Window system.

  • This module has a different API.

  • This module doesn't assign a locale to a database.

  • This module doesn't associate types with values.

  • This module can't read or write config files with multi-line values

SUPPORT

Bugs

Please report any bugs or feature requests to bug-config-xrmdatabase@rt.cpan.org or through the web interface at: https://rt.cpan.org/Public/Dist/Display.html?Name=Config-XrmDatabase

Source

Source is available at

  https://gitlab.com/djerius/config-xrmdatabase

and may be cloned from

  https://gitlab.com/djerius/config-xrmdatabase.git

SEE ALSO

Please see those modules/websites for more information related to this module.

AUTHOR

Diab Jerius <djerius@cpan.org>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2021 by Smithsonian Astrophysical Observatory.

This is free software, licensed under:

  The GNU General Public License, Version 3, June 2007