NAME
    Rose::DBx::RegistryConfig - Rose::DB with auto-registration of data
    sources from YAML configuration file

DESCRIPTION
    Rose::DBx::RegistryConfig helps you work with data source definitions in
    YAML-based configuration files, supporting multiple "namespace
    representations." It allows you to register Rose data sources without
    hard-coding anything directly in source code.

MOTIVATION
    Using configuration files to store data source definitions instead of
    putting this information (which amounts to configuration details)
    directly in source code (as is typically done when using Rose::DB) is a
    valuable convenience in general. It becomes especially valuable as the
    number of data sources increases.

    The end goal is to cleanly organize configuration data. This is not just
    a matter of aesthetics. Small, self-contained configuration files reduce
    error and save time. They are naturally easy to maintain.

SYNOPSIS & IMPORT ARGUMENTS
        #------- First create a local subclass (recommended):
        package My::DB;
        use base qw( Rose::DBx::RegistryConfig );
        ...
        1;
        __END__

        #------- Then use it in your client code:

        # Use with a DOMAIN_CONFIG file to auto-register all domains:
        use My::DB
            default_domain  => 'devel',
            default_type    => 'mydb',
            domain_config   => '/path/to/DOMAIN_CONFIG';

        # ...or register only a subset of the domains in DOMAIN_CONFIG:
        use My::DB
            domain_config   => '/path/to/DOMAIN_CONFIG',
            target_domains  => [ qw( domain1 domain2 ) ];

        # ...or just use an existing registry:
        use My::DB
            registry        => $registry;   # ($registry defined at compile-time)

        # ...a custom namespace representation can also be supported instead of the default:
        use My::DB
            domain_config   => '/path/to/DOMAIN_CONFIG',
            parse_domain_hash_callback  => \&my_domain_parser;

        # (after 'use()'ing, proceed as you would with Rose::DB...)

    Rose::DBx::RegistryConfig is a specialization of Rose::DB. Understanding
    the basic usage of Rose::DB is essential.

    Rose::DBx::RegistryConfig provides some alternative ways for working
    with the Rose::DB Registry. Beyond that sphere of responsibility, it
    behaves like Rose::DB. As with Rose::DB, Rose::DBx::RegistryConfig is
    intended to be subclassed.

    Most interaction with the interface usually takes place via "import"
    arguments (arguments to "use"). However, all "import" arguments are
    optional.

    Import arguments for basic class-wide settings...

    "default_domain"
        Define the class-wide default domain.

    "default_type"
        Define the class-wide default type.

    Arguments for initializing the data source registry from the
    DOMAIN_CONFIG file are also accepted. See the arguments by the following
    names in conf2registry:

    "domain_config"
    "target_domains"
    "parse_domain_hash_callback"
    ...or, mutually-exclusive to arguments dealing with DOMAIN_CONFIG:

    "registry"
        A pre-made data source registry object. This allows you to
        explicitly cause an existing registry to be used (NOTE that setting
        this argument with "use" constitutes the use of variable data at
        compile time, so the registry must be available then, e.g. by
        creating it in a BEGIN block).

  Tip: dynamically setting "import" arguments
    When you need to dynamically set arguments to use(), make sure that they
    are defined at compile time:

        # Importing with dynamic arguments...
        my $domain_config;
        BEGIN {
            $domain_config = get_rose_dbx_domains_from_somewhere();
        }
        use Rose::DBx::RegistryConfig
            default_domain  => $default_domain,
            default_type    => $default_type,
            domain_config   => $domain_config;

DOMAIN_CONFIG
    DOMAIN_CONFIG is a YAML file containing data source definitions.
    Rose::DBx::RegistryConfig interprets the following namespace
    representation by default:

        # an example domain specifically for a collection of similar databases:
        dev-private:
            defaults:
                driver:     mysql
                host:       dbhost
                username:   me
                password:   foo
            DATASET_A:
            DATASET_B:
            DATASET_C:
            DATASET_D:
            DATASET_E:
        ---
        # another domain:
        otherdomain:
            defaults:
                somemethod:     somevalue
            sometype:
                othermethod:    othervalue
        
    This namespace representation is used as the Rose::DBx::RegistryConfig
    default because the Rose::DB default representation leads to a large
    amount of redundant information for configurations that involve many
    similar databases.

    Note especially the following about this namespace representation:

    *   The standard namespace representation used by Rose for ROSEDBRC and
        "auto_load_fixups" is the same as this one except it does not have a
        'defaults' pseudo-type and is more explicit. This means that either
        representation can be used with Rose::DBx::RegistryConfig.

    *   DOMAIN_CONFIG must consist of a sequence of Rose domains, which each
        contain Rose types and their definitions.

    *   In addition to the normal types of Rose::DB, the 'defaults'
        pseudo-type is recognized. The domain parser assumes the default
        value for each attribute that is not defined for a type. Thus, in
        the above example, all DATASET data sources will have the value
        'mysql' for the driver attribute, 'dbhost' for the host, etc.

    *   The DATASET_X type names have no 'database' method/value even though
        the defaults do not provide a database attribute. Where does the
        database name come from? The default domain parser knows to use the
        type name (DATASET_X) as the database name if the attribute is
        omitted.

    *   This representation is also supported in the "fix-ups" file used for
        the ROSEDBRC/"auto_load_fixups" feature.

    Alternative representations may be handled using a domain parser, but
    NOTE the following restriction: DOMAIN_CONFIG should consist of a set of
    domain names (the top-level keys). The values can define types in any
    way desired, as long as it's YAML. If this is too restrictive then set
    the registry explicitly.

CLASS METHODS
  conf2registry
        my $reg = Rose::DBx::RegistryConfig->conf2registry(
            domain_config   => $domain_config,
            target_domains  => [ 'd1', 'd2', 'd3' ],
            parse_domain_hash_callback  => \&my_domain_parser,
        );

    Parse DOMAIN_CONFIG and use its contents to create a data source
    registry. This allows data source definitions to be kept in a file
    instead of in source code, which is encouraged because data source
    definitions are, conceptually, configuation data.

    "domain_config"
        (Required)

        This allows you to specify the path to DOMAIN_CONFIG. With this
        import argument, a data source registry is automatically created for
        this class based on the data sources defined in your DOMAIN_CONFIG
        file.

    "target_domains"
        An array of domain names for auto_registration. This defines the set
        of domains which will be auto-registered. All other domains will be
        excluded. This lets you ensure that only a subset of the data source
        definitions in DOMAIN_CONFIG will be registered, which might be
        useful if DOMAIN_CONFIG is being used for multiple tasks or multiple
        apps.

    "parse_domain_hash_callback"
        A subroutine reference to a caller-defined alternative to the
        default domain parser. It is called with the same arguments as the
        default domain parser and is responsible for the same task. It
        differs only in that it is used to implement an alternative
        namespace representation.

  parse_domain
    This method is the class-wide default domain parser, responsible for
    creating a set of registry entries from a data structure that represents
    a domain. It recognizes the class-wide default data source namespace
    representation.

    The domain parser is called automatically for each domain in
    DOMAIN_CONFIG. It must interpret a given domain data structure, which
    should represent a single domain in the data source registry, as a set
    of registry entries. These entries are added to the provided registry
    object, which is finally returned.

    "registry"
        (Required. Must be a descendant of Rose::DB::Registry.)

        A Rose::DB::Registry object to operate on.

    "domain_name"
        (Required)

        The name of the domain to be registered.

    "domain_hashref"
        (Required)

        Data structure containing the definition of the domain to be
        interpreted.

SUBCLASSING
    See the notes about derived classes in the Rose::DB documentation.

    Additionally, subclasses may implement a class-wide default data source
    namespace representation by overriding the default domain parser.

    Note also that if your subclass is to support your new namespace
    representation for the ROSEDBRC/"auto_load_fixups" feature (doing this
    where applicable is a good idea for consistency -- it would be best to
    use the same representation for ROSEDBRC and DOMAIN_CONFIG), you also
    need to override load_yaml_fixups_from_file.

  auto_load_fixups
    This method overrides "auto_load_fixups" in Rose::DB. This is done so
    that alternative namespace representations can be used within ROSEDBRC.
    Aside from supporting alternative representations, this method functions
    in the same way. See load_yaml_fixups_from_file.

  load_yaml_fixups_from_file
    This method is called by auto_load_fixups when a file is being used to
    indicate "fix-up" information. Subclasses should override it if an
    alternative namespace representation is being used.

    It is called as a class method with one (additional) argument: the name
    of the ROSEDBRC file containing fix-up data.

DIAGNOSTICS
    "DOMAIN_CONFIG file '...' not found"
        The supplied path for DOMAIN_CONFIG was not found.

    "param '...' required"
        Missing a required subroutine parameter.

    "param '...' must be a <class> object"
        A given subroutine parameter is not an object of the required type
        (<class>).

CONFIGURATION AND ENVIRONMENT
    See Rose::DB. Rose::DBx::RegistryConfig adds the following features that
    impact configuration/environment:

    DOMAIN_CONFIG

DEPENDENCIES
    Carp

    YAML

    Rose::DB

LICENSE AND COPYRIGHT
    Copyright (c) 2009 Karl Erisman (karl.erisman@icainformatics.com), ICA
    Informatics. All rights reserved.

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

ACKNOWLEDGEMENTS
    Thanks to ICA Informatics for providing the opportunity for me to
    develop and to release this software. Thanks also to John Ingram for
    ideas about the simplified representation of the default DOMAIN_CONFIG,
    which is helping us reduce the complexity of our configurations
    significantly.

    Thanks also to John Siracusa for the Rose family of modules and for
    providing guidance in the form of answers to questions about development
    of this module.

AUTHOR
    Karl Erisman (karl.erisman@icainformatics.com)

