Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Rose::DB::Tutorial(3) User Contributed Perl DocumentationRose::DB::Tutorial(3)

NAME
       Rose::DB::Tutorial - Best practices for using Rose::DB

INTRODUCTION
       This tutorial describes "best practices"	for using Rose::DB in the most
       robust, maintainable manner.  It	does not replace the actual
       documentation, however.	The actual Rose::DB documentation is still
       essential, and contains some good examples of its own.

       In particular, you should read the description section of the Rose::DB
       documentation if	you have not done so already.  It describes the
       features	and philosophy of Rose::DB.  That information that will	not be
       repeated	here.

CONVENTIONS
       The examples in this tutorial will use the fictional "My::" namespace
       prefix.	Your code should use whatever namespace	you deem appropriate.
       Usually,	it will	be more	akin to	"MyCorp::MyProject::" (i.e., your
       corporation, organization, and/or project).  I've chosen	to use "My::"
       simply because it's shorter, and	will help this tutorial	stay within an
       80-column width.

       For the sake of brevity,	the "use strict" directive and associated "my"
       declarations have been omitted from the example code.  Needless to say,
       you should always "use strict" in your actual code.

       Similarly, the traditional "1;" true value used at the end of each
       ".pm" file has been omitted from	the examples.  Don't forget to add
       this to the end of your actual Perl module files.

TUTORIAL
   Creating a subclass
       The first step when using Rose::DB in anything but a throw-away script
       is to create a trivial subclass.	 This is important because Rose::DB
       has a significant amount	of class data.	Using Rose::DB directly	means
       that you	will be	reading	and writing the	same data as any other badly-
       behaved code that also uses Rose::DB directly.

       In particular, the registry that	contains all the information for each
       data source is class data, and is inherited from	(that is, shared with)
       the base	class by default.  Creating a subclass allows you to have your
       own, private data source	registry.

       So, here's our initial Rose::DB subclass.

	 # File: My/DB.pm
	 package My::DB;

	 use Rose::DB;
	 our @ISA = qw(Rose::DB);

	 # Use a private registry for this class
	 __PACKAGE__->use_private_registry;

   Designing your namespace
       As described in the Rose::DB documentation, Rose::DB provides a two-
       level namespace for data	sources, made up of a "domain" and a "type."
       These are both arbitrary	strings, so there's a lot of freedom to	break
       up the namespace	in any way you see fit.	 For example, sub-domains and
       sub-types can be	created	within each string using delimiter characters
       (e.g., "::" as in Perl's	package	namespace).

       But let's back up.  The simplest	case is	that you have just one data
       source, and therefore no	need for a namespace at	all.  If this is the
       case, you can skip to the next section.

       In the common case, it's	usually	sufficient to use simple words for
       both type and domain.  As the name "domain" implies, this value usually
       represents the environment or surroundings.  For	example, a typical
       server application might	use domains named "development", "qa",
       "staging", and "production".

       The "type" portion of the namespace tends to be used to differentiate
       the applicability or contents of	the data sources.  Some	example	type
       names are "main"	for the	primary	database, "archive" for	a data
       warehouse database, and "session" for a database	used to	store
       transient session data.

       The goal	of namespace design is to allow	data sources to	be referred to
       symbolically, with names	that make sense	to you in your environment.

   Registering data sources
       Now that	you've decided on your namespace design	(or lack thereof, if
       you have	only one data source), it's time to register some data
       sources.	 To register a data source, call the register_db class method.

       This can	be done	nearly anywhere, but it's most convenient to do	it
       "early" and to link it somehow to your "My::DB" subclass.  That is,
       when someone "use"s "My::DB", they should not have to worry about
       whether or not all the data sources are registered.

       In a server environment,	there's	usually	some sort of start-up file
       that gets loaded	before any "end-user" code (e.g., "startup.pl" by
       convention in a mod_perl	Apache web server).  That may be a good	place
       to include your data source registration	calls, but only	if you're
       absolutely sure that "My::DB" will never	be used	outside	the server
       environment.

       A better, safer alternative is to put the data source registration
       calls directly in your Rose::DB subclass.  This is the recommended
       approach.  Here are some	examples.

       Just one	data source

       First, consider the case	where a	namespace is not necessary.  You have
       a single	data source and	that's all.  You don't care what it's named.
       Luckily,	there are default values for both type and domain.  Simply
       register	your data source using these values and	you're all set.

	   package My::DB;

	   use Rose::DB;
	   our @ISA = qw(Rose::DB);

	   # Use a private registry for	this class
	   __PACKAGE__->use_private_registry;

	   # Register your lone	data source using the default type and domain
	   __PACKAGE__->register_db(
	     domain   => My::DB->default_domain,
	     type     => My::DB->default_type,
	     driver   => 'pg',
	     database => 'my_db',
	     host     => 'localhost',
	     username => 'joeuser',
	     password => 'mysecret',
	   );

       The domain and type parameters can actually be omitted entirely and
       they will still default to the values shown above.  In other words, the
       following call to register_db is	exactly	equivalent to the one above.

	   # Register your lone	data source using the default type and domain
	   __PACKAGE__->register_db(
	     driver   => 'pg',
	     database => 'my_db',
	     host     => 'localhost',
	     username => 'joeuser',
	     password => 'mysecret',
	   );

       To use "My::DB" in this kind of setup, simply omit the domain and type
       parameters from your calls to "My::DB->new".  They will automatically
       get the default values.

	   use My::DB;

	   $db = My::DB->new();	# use default type and default domain
	   print $db->username;	# "joeuser"
	   $dbh	= $db->dbh;	# connect and get DBI database handle

       Multiple	data sources

       Most commonly, you will have more than one data source.	(And if	you
       don't now, you probably will in the future.  Better safe	than sorry.)
       After you've designed your namespace, data source registration is
       straightforward.	 The only wrinkle is how to deal with the default
       domain and type.

       I recommend setting the default domain and type to the "safest" values
       in your environment.  For example, a domain of "development" and	a type
       of "main" are reasonable	choices.  This allows you to use "bare"	calls
       to "My::DB->new()" in your code (as shown in the	simple,	single data
       source example above).

       Here's an example that includes two domains "development" and
       "production", and two types, "main" and "session."  The default data
       source is the domain "development" and the type "main".

	   package My::DB;

	   use Rose::DB;
	   our @ISA = qw(Rose::DB);

	   # Use a private registry for	this class
	   __PACKAGE__->use_private_registry;

	   # Set the default domain and	type
	   __PACKAGE__->default_domain('development');
	   __PACKAGE__->default_type('main');

	   # Register the data sources

	   # Development:

	   __PACKAGE__->register_db(
	     domain   => 'development',
	     type     => 'main',
	     driver   => 'pg',
	     database => 'dev_db',
	     host     => 'localhost',
	     username => 'devuser',
	     password => 'mysecret',
	   );

	   __PACKAGE__->register_db(
	     domain   => 'development',
	     type     => 'session',
	     driver   => 'mysql',
	     database => 'session_db',
	     host     => 'localhost',
	     username => 'devmysql',
	     password => 'mysqlpw',
	   );

	   # Production:

	   __PACKAGE__->register_db(
	     domain   => 'production',
	     type     => 'main',
	     driver   => 'pg',
	     database => 'big_db',
	     host     => 'dbserver.mycorp.com',
	     username => 'dbadmin',
	     password => 'prodsecret',
	   );

	   __PACKAGE__->register_db(
	     domain   => 'production',
	     type     => 'session',
	     driver   => 'mysql',
	     database => 'session_db',
	     host     => 'sessions.mycorp.com',
	     username => 'session_user',
	     password => 'prodsesspw',
	   );

       Ideally,	and as shown in	the example above, all data source types are
       available in each domain.  Combined with	the consistent practice	of
       never specifying	an explicit domain when	constructing your "My::DB"
       objects,	this allows the	domain to be switched as needed, without
       modifying any code in the actual	application.

       For example, imagine a mod_perl Apache web server environment running
       application code	that constructs	its "My::DB" objects like this:

	   $main_db    = My::DB->new('main');
	   $session_db = My::DB->new('session');

       Now imagine a "startup.pl" file that contains the following:

	   # File: startup.pl
	   use My::DB;

	   if($ENV{'MYCORP_PRODUCTION_SERVER'})
	   {
	     My::DB->default_domain('production');
	   }
	   else
	   {
	     My::DB->default_domain('development');
	   }

       This deliberate use of defaults combined	with a healthy dose of
       convention in your constructor calls can	make it	simple to move your
       code from one environment to another without any	changes	beyond the
       usual configuration management that must	be done	(e.g., for apache
       configuration files).

       The determination of the	current	environment can	be done	in many
       different ways, of course.  Checking an environment variable as shown
       above is	probably not the best way to do	it, but	it makes for a simple
       example.

       Another alternative is to use some sort of configuration/build
       management system to generate the Apache	configuration files from
       templates.  In that case, the templates could contain something like
       this:

	   [% IF in_production %]
	       My::DB->default_domain('production');
	   [% ELSE %]
	       My::DB->default_domain('development');
	   [% END %]

       This would leave	only the single, appropriate call in the completed
       "startup.pl" file.

   Using your database objects
       Before trying to	use Rose::DB objects, it's important to	understand the
       primary goals of	Rose::DB.  The features	are described in the Rose::DB
       documentation, but there	is one thing that is left unsaid.  Although
       Rose::DB	is useful in isolation and provides many convenient methods
       and abstractions, its primary purpose is	to encapsulate database-
       specific	behaviors on behalf of Rose::DB::Object.

       Of course, it could fill	the same role for any Rose::DB::Object-like
       module, and for any code	that does the same kinds of things.  If	you
       need to parse or	format vendor-specific column values or	want to	use a
       simple form of reference	counting to keep track of shared database
       handles,	you may	find Rose::DB useful.

       The most	common non-Rose::DB::Object-related use	for Rose::DB is	as a
       way to get a DBI	database handle	without	sweating the details of	how
       it's created or where it's connected.  The previous sections of this
       tutorial	cover everything you need to know to set up Rose::DB to	be
       used in this capacity.  Please be sure to read the Rose::DB
       documentation as	well, particularly the database	handle life-cycle
       management section.

DEVELOPMENT POLICY
       The Rose	development policy applies to this, and	all "Rose::*" modules.
       Please install Rose from	CPAN and then run "perldoc Rose" for more
       information.

SUPPORT
       Any Rose::DB questions or problems can be posted	to the
       Rose::DB::Object	mailing	list.  (If the volume ever gets	high enough,
       I'll create a separate list for Rose::DB.  But it isn't an issue	right
       now.)  To subscribe to the list or view the archives, go	here:

       <http://groups.google.com/group/rose-db-object>

       Although	the mailing list is the	preferred support mechanism, you can
       also email the author (see below) or file bugs using the	CPAN bug
       tracking	system:

       <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Rose-DB>

       There's also a wiki and other resources linked from the Rose project
       home page:

       <http://rosecode.org>

AUTHOR
       John C. Siracusa	(siracusa@gmail.com)

COPYRIGHT
       Copyright (c) 2007 by John C. Siracusa.	All rights reserved.  This
       program is free software; you can redistribute it and/or	modify it
       under the same terms as Perl itself.

perl v5.32.0			  2015-03-18		 Rose::DB::Tutorial(3)

NAME | INTRODUCTION | CONVENTIONS | TUTORIAL | DEVELOPMENT POLICY | SUPPORT | AUTHOR | COPYRIGHT

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Rose::DB::Tutorial&sektion=3&manpath=FreeBSD+12.1-RELEASE+and+Ports>

home | help